Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: выделение скобок и кавычек
 
 автор: kotsugai   (26.01.2009 в 21:12)   письмо автору
 
 

Доброе время суток, уважаемые форумчане, у меня в настоящее время возникла некторая проблема, помощь в решении которой хотелось бы услышать :)))

Есть строчка:
operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );


есть выражение:
'#([a-z0-9\._@]+)|[.,;+-/=*]|(\(.+\))|(\[.+\])|\"[^\"]*\"#i'


и получается результат:

Array
(
    [0] => operator
    [1] => @var_type
    [2] => @var_name
    [3] => [ = @var_data ] (, @var_type @var_name [ = @var_data ]
    [4] => ;
)

возникла проблема, что первые квадратные скобки должны быть в 3 строчке, следом круглые скобки и всё их содержимое в 4 позиции и в пятой точка с запятой.
при всех моих попытках объеденяются скобки, помогите в решении сией задачи.

Попутно возникает вопрос, как можно выделить кавычки и пропустить в исходной строчке последовательность \" ?

Заранее премного благодарен, с уважением, Kotsugai.

  Ответить  
 
 автор: xx7   (26.01.2009 в 23:05)
 
   для: kotsugai   (26.01.2009 в 21:12)
 

не понятно есть-ли только эта такая строка
, или есть текст содержащий массу таких и других строк.
По вопросу похоже на реализацию подсветки синтаксиса , какого-то из языков программирования ,
такое наверное не сделать одним выражением .
под \* имелось ввиду что-то типа /*таких*/ комментариев ?

А так просто в выражении \[.+\] жадный модификатор + , который вберёт всё до последней закрывающей \]
, можно инвертировать жадность как "+?"

  Ответить  
 
 автор: xx7   (26.01.2009 в 23:09)
 
   для: xx7   (26.01.2009 в 23:05)
 

прибавил размеру буквам ,) оказалось \" ;)
тогда не понятно выделять-ли строку в каычках , или строку в скобках , если какая-либо из строк внутри другой строки

  Ответить  
 
 автор: kotsugai   (27.01.2009 в 11:40)   письмо автору
 
   для: xx7   (26.01.2009 в 23:05)
 

А так просто в выражении \[.+\] жадный модификатор + , который вберёт всё до последней закрывающей \]

+ ставил для того, чтобы повторялся оператор точка, по поводу жадности не знал, спасибо

по поводу языка программирования, ты почти попал в точку, мне нужно разделить символы на группы и то что в скобках и кавычках я потом повторно просканирую, потому мне нужно чтобы
скобки были парными

по поводу груп строчек и кавычек мне нужно, чтобы выделялись кавычки с пропуском последовательностей \"
чтобы в кавычках шло как одно целое также со скобками
поясню:
[ = @var_data ] (, @var_type @var_name [ = @var_data ] );
отделить первую группу скобок от второй

[ = @var_data ]
и вторая:
(, @var_type @var_name [ = @var_data ] )

и в случае парных скобок (выражение, (выражение)) не определял как
(выражение, (выражение)
или
(выражение))

  Ответить  
 
 автор: kotsugai   (27.01.2009 в 11:45)   письмо автору
 
   для: kotsugai   (27.01.2009 в 11:40)
 

также удовлетворю твоё любопытсво
вот примеры анализируемых строчек:

operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );

create number num_1;
operator variable var_1;
operator var_1,var_2=34868.0,var_3;

duplicate @array[var1,var2,(var3)];
print "qwrqwr qwrqwr", "wetwet\wet", @array[34];


у меня строчка разделяется на более мелкие группы - срез (знаки припинания, слова, то что в скобках )
потом то же делается для маски и затем сверяются оба среза
если ни одна из масок не совпадает с исходным утверждением, оператор не существует
для синтаксиса проверка более простая, делается срез выражения, в исходной строке исключаются повторные пробелы и лишние знаки, затем идет сверка обоих строк
если они совпадают, то синтаксис верный, если нет - ошибка :))))

прототип языка - MySQL, пришлось на нем программировать и есть изъяны, которые нынче собираюсь исправить и улучшить

  Ответить  
 
 автор: xx7   (27.01.2009 в 18:25)
 
   для: kotsugai   (27.01.2009 в 11:45)
 

>по поводу жадности не знал, спасибо
да ладно, не стОит ,) тем-более я незаметивши обозвал квантификатор (оператор повторения)
, модификатором :)

Насчёт анализа строк, думаю такое лучше делать на perl или на си.
В php немного затёрто понятие строки как массива , нет возможности обратиться к части строки начиная с нужного индекса, а только к символу , как $string{$x}, или можно просто получить чакть как substr($string, $x)
С выражениями примерно так-же , нет циклов где можно было-бы обрабаывать каждое совпадение
и изменять по мере надобности само выражение в условии цикла
, а есть только такие "полуавтоматы"( незнаю правильно-ли обозвал :))
, как например preg_replace_callback()

можно сделать типа цикла, в простейшем случае например такого
<pre style="font:normal 105% Lucida Console"><?
$txt 
'operator @var_type @var_name [ = @var_data ] (, @var_type @var_name [ = @var_data ] );

create number num_1;
operator variable var_1;
operator var_1,var_2=34868.0,var_3;

duplicate @array[var1,var2,(var3)];
print "qwrqwr qwrqwr\"\\\\", "w\"et\we", @array[34];
'
;
$str '([\'"])(?>(?:\x5c.|(?!\1).)?[^\x5c"\']*)+\1\s*';
$ind '\[[^\]]*\]\s*';

$re2 '#' $str '|' $ind .'|([\.0-9]+)'
        
.'|(@?[A-Za-z][0-9A-Z_a-z]*)|([,;=])#';

function 
xpars($m){
    
print_r($m);
static 
$opr false// оператора небыло
$color = ($opr) ? 'darkred''darkblue';

if (!isset(
$m[1])) return '<i style="color:blue">'
    
$m[0] .'</i>';
if (
$m[1]) return '<i style="color:red">'
    
$m[0] .'</i>';
if (
$m[2]) return '<b style="color:darkgreen">'
    
$m[0] .'</b>';
if (
$m[3]) {
    if (!
$opr) {
        
$opr true;
    }
    return 
'<b style="color:'
        
$color .'">'$m[0] .'</b>';
}
if (
$m[4]) {
    if (
$m[0] == ';'$opr false;
    return 
'<b style="font:bold 130% impact">'
    
$m[0] .'</b>';
}
return 
$m[0];
}

print 
$txt preg_replace_callback($re2'xpars'$txt);
?>

Но получается у меня чем качественнее пытаюсь разобрать такое, тем медленнее всё это работает

само по себе построение шаблона как набор альтернатив 'первое|второе|третье|......' неслабо замедляет всё это дело
плюс ещё пожоже придётся использовать ещё вызовы preg_функций() внутри callback-функции
, например чтобы не искать так оператор среди одинаковых слов, а выбрать вса слова и обозначить какое для чего.
, или для разбора @array[@var[1], var2[2][1]] , придётся использовать (?(R)) в шаблоне , что тоже не намного облегчит анализ .
Ещё и не видно пока операторов кроме "=" , а думаю они наверняка есть
полностью всё правильно разобрать в таких более-менее сложных синтаксисах, можно только воссоздав логику самого интерпритатора этих комманд,
(а они обычно используют или посимвольное чтение , или например сишную sscanf()),
или заставить сам интерпритатор разобрать всё это

  Ответить  
 
 автор: xx7   (27.01.2009 в 18:30)
 
   для: xx7   (27.01.2009 в 18:25)
 

>понятие строки как массива
наверное жотел сказать что затёрто понятие работы с указателями :)

  Ответить  
 
 автор: kotsugai   (28.01.2009 в 00:09)   письмо автору
 
   для: xx7   (27.01.2009 в 18:30)
 

во спс, ток я несколько проще сделал, покапался и узнал про такую хорошую вещь, как рекурсия, вот что вышло:

function id_analyse($message)
    {
    $msk1 = '(@?[\w\d_.]+)';                     // операторы и переменные
    $msk2 = '(\d+(,\d+)?)';                      // числа
    $msk3 = '[.,;+-/=*]';                    // разделители и операторы
    $msk4 = '\(((?>[^()]+)|(?R))*\)';        // круглые скобки
    $msk5 = '\[((?>[^\[\]]+)|(?R))*\]';        // квадратные скобки
    preg_match_all  ('#'.$msk1.'|'
                        .$msk2.'|'
                        .$msk3.'|'
                        .$msk4.'|'
                        .$msk5.'|\"[^\"]*\"#i',$message,$buff);
    
    //preg_match_all('#"([^"])*"#i',$message,$buff);
    
    echo '<pre>'.$message.'<br>';
    print_r($buff[0]);
    echo '</pre><hr>';
    
    return $buff[0];
    }


правд со скобками запарка вышла :(

не срабатывает на строчке
print "qwrqwr qwrqwr", "wetwet\"wet", @array[34];

и числа всеж в мск_1 проверяются :)))))
т.е. пройдут числа 23.34_wqr

  Ответить  
 
 автор: xx7   (28.01.2009 в 01:00)
 
   для: kotsugai   (28.01.2009 в 00:09)
 

есть несколько способов пропускать заэкранированное
, типа такого например
<?
'#'.$msk1.'|' 
                        
.$msk2.'|' 
                        
.$msk3.'|' 
                        
.$msk4.'|' 
                        
.$msk5.'|'
        
.'"(?>(?:\x5c.)?[^\x5c"]*)+"#i'

только со слэшами всё время непонятки, даже если строка в апострофах , нужно ставить в ней два двойных, чтобы получить двойной слэш
и в php , почему-то у меня многое только получается только если в выражениях ставить \x5c вместо слэша
(с подмасками тоже замечал баги , но щас точно не воспроизведу)

  Ответить  
 
 автор: xx7   (28.01.2009 в 01:08)
 
   для: kotsugai   (28.01.2009 в 00:09)
 

[\w\d_.] не совсем точно [\w\.] это то-же самое
[.,;+-/=*] здесь лучше всё экранировать , например "-" будет понят как диапазон символов от + до /
и модификатор ./i наверное не нужен

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования