Помогите составить регулярное выражение

ilkz

Новичок
Помогите составить регулярное выражение

Есть нижеприведенный код. Задача состоит в том, чтобы научить его выдирать из файла-шаблона (или массива строк) спецтеги, которые впоследствии обрабатываются движком. Сначала хотел все сделать стандартными строковыми функциями, но понял что это - тупик :). Выход из тупика - регулярки. Попытка заюзать POSIX RegExp не привела к желаемому результату. Тогда было принято решение использовать PCRE. И вот что получилось:
PHP:
<?
function ExtractTags( $string )
{
    for($i=0; $i<count($string);$i++)
	{
		if( preg_match("/###\[ *(\w+) +(\w+=[\"\w\"]+)+ *\]/",$string[$i],$match) ) //ищем в строке спецтег
			echo "найден тег: <b>".$match[1]."</b> со значенями: <b>".$match[2]."</b>\n";
	}
        return 1;
}

$f=file("index");

echo "<pre>\n";
ExtractTags($f);
echo "</pre>";
?>
Все бы хорошо, НО. Сей код почему-то ищет ТОЛЬКО спецтеги такого вида:
###[TagName Property="Value"]. Но в задаче стоит цель научить алгоритм понимать множество свойств тега.
По идее, регэксп составлен правильно, ведь участок (\w+=[\"\w\"]+)+, а точнее, плюсик в его конце и должен заставлять ПХП искать более одного свойства... Но - он упорно не хочет понимать более одного свойства..... Похоже, что я еще немножко чайник :)

Помогите, если эта возможность у Вас есть. Спасибо!
 

ilkz

Новичок
Да нет - вроде бы все верно: квадратные скобки [\"\w\"]+ означают примерно следующее: "набор символов кавычка-любая_буква-кавычка, причем сия конструкция может повторяться более одно раза. Верно?
 

SelenIT

IT-лунатик :)
Да не совсем - по идее это означает "любой алфавитно-цифровой символ, знак подчеркивания либо двойная кавычка, в количестве не менее одной штуки". Квадратные скобки (в отличие от круглых) - это ограничитель класса символов.
 

ilkz

Новичок
Ага, значит, если цель будет без кавычки, то регэксп ее тоже примет за верную?.. Тогда как сделать, чтобы он воспринимал эту констукцию (\"\w\") как единое целое? Ставить круглые скобки? Но тогда это будет являться "карманом"... Не понимаю, е-мое...
 

SelenIT

IT-лунатик :)
Возможно, подойдет что-то вроде такого: (\"(\w+)\")?
Для наглядности дай пример обрабатываемой строки и того, что из нее нужно получить.
 

ilkz

Новичок
Даю. Для наглядности :)))
PHP:
<html>
<link rel="stylesheet" type="text/css" href="styles.css">
<meta charset=windows-1251>
<META NAME="keywords" CONTENT="Новинки софта, полезные советы, свежие статьи, downloads, аниме, программы,
софт, кряк, радиотехника, электроника, схемы, плата, мультики, хентай, видео, картинки, галерея, скачать,
музыка">
<META NAME="anime, radio, mp3, soft, download, freeware, hentai, wallpapers, software, windows, unix">
<META name="author" content="Новинки софта, полезные советы, свежие статьи, downloads ...">
<META name="copyright" content="Новинки софта, полезные советы, свежие статьи, downloads ...">
<title>###[title caption="Hello"]</title>
<body bgcolor=#FFFFFF>

<noscript><body></noscript>
<table bgcolor=#FFFFFF width=950 height=500 border=0>

<tr>
  <td colspan=2 height=100><img src="templates/top.jpg" align="center" border=1></td>
</tr>

<tr>
  
  <td width=140>
  <div class="menu">
###[menu type="main_menu"]
###[banner type="small" alt="Реклама"]

###[fucked_tag]

<!-- HotLog -->
<script language="javascript">
hotlog_js="1.0";
hotlog_r=""+Math.random()+"&s=246989&im=131&r="+escape(document.referrer)+"&pg="+
escape(window.location.href);
document.cookie="hotlog=1; path=/"; hotlog_r+="&c="+(document.cookie?"Y":"N");
</script><script language="javascript1.1">
hotlog_js="1.1";hotlog_r+="&j="+(navigator.javaEnabled()?"Y":"N")</script>
<script language="javascript1.2">
hotlog_js="1.2";
hotlog_r+="&wh="+screen.width+'x'+screen.height+"&px="+
(((navigator.appName.substring(0,3)=="Mic"))?
screen.colorDepth:screen.pixelDepth)</script>
<script language="javascript1.3">hotlog_js="1.3"</script>
<script language="javascript">hotlog_r+="&js="+hotlog_js;
document.write("<a href='http://click.hotlog.ru/?246989' target='_top'><img "+
" src='http://hit10.hotlog.ru/cgi-bin/hotlog/count?"+
hotlog_r+"&' border=0 width=88 height=31 alt=HotLog></a>")</script>
<noscript><a href=http://click.hotlog.ru/?246989 target=_top><img
src="http://hit10.hotlog.ru/cgi-bin/hotlog/count?s=246989&im=131" border=0 
width="88" height="31" alt="HotLog"></a></noscript>
<!-- /HotLog -->
  </div>
  </td>
  
  <td width=810 class="contentzone"><img src="templates/menu.jpg" align="left">
  <br>
  <div class="td">
###[content align="center"]
###[   banner       type="big" alt="Большая реклама"]
  </div>
  </td>
</tr>

</table>

</body></html>
Вот такой код. А вот вывод:
найден тег: title со значенями: caption="Hello"
найден тег: menu со значенями: type="main_menu"
найден тег: content со значенями: align="center"
 

SelenIT

IT-лунатик :)
ilkz
Вот такой вариант, если заранее известно максимальное число параметров твоих псевдотегов - в примере максимум 3:
PHP:
preg_match_all('!###\[\s*(\w+)(\s+(\w+)="([^"]+)")(\s+(\w+)="([^"]+)")?(\s+(\w+)="([^"]+)")?\]!',$text,$tags,PREG_SET_ORDER);
print_r($tags);
 

ilkz

Новичок
Я думаю, что больше трех параметров у тега вряд ли будет :)
"^__^ Теперь дооолго буду втыкать в сие творение человеческой мысли...
Аригато!
 

SelenIT

IT-лунатик :)
\s* и \s+ появились исключительно из-за последнего примера
Код:
(###[   banner       type=...)
[^"]+ - не кавычки, минимум один символ
(что-то)? - то ли будет, то ли нет
вроде, все понятно ;)
 
Сверху