Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Регулярные выражения в парсере (https://javascript.ru/forum/misc/5482-regulyarnye-vyrazheniya-v-parsere.html)

Paguo-86PK 18.10.2009 02:42

Регулярные выражения в парсере
 
Сколько ни читаю, а одолеть суть не могу... Регулярные выражения - самая сложная область у Perl, PHP и JS.

Простой пример:
Типичное форумское
[URL=location title="Hint"]Address[/URL]

Как здесь нужно описать регулярое выражение, чтобы выловить и тэг URL, и location, и Hint, и Address?
А то замучался писать сам алгоритмы с разбором строк.

Или вот интерпретатор языка.
Например:
•var_2 = '• Example #1'• Commentary #2
••var_1 = "var_2 = \"• Don't cry...\" + 'Why?';" + var_2• Commentary #1 ••
Здесь мой алгоритм работает так:
Если в начале строки идёт ряд из "•", он их подсчитывает. До первого любого символа.
Затем эти "•" не должны попадаться вне строк ('...' или "..."), иначе они указывают на обрыв выражения и начало комментария.

Мой скрипт с этим справляется, но содержит много строк и довольно сложен в отладке. Одно введение новой конструкции - снова перестаёт работать и требует длительной отладки.

Могут ли и тут помочь регулярки? Чтобы легко получить три аргумента:
#1: Количество "•" вначале строки;
#2: Само выражение до конца строки или до символа "•", если он не заключём в '...' или в "...";
#3: Строка, отделённая от основного выражения символом "•". Содержит что угодно как комментарий.

Приведённые выше строки должны преобразоваться:
из
•var_2 = '• Example #1'• Commentary #2
в
#1: 1
#2: var_2 = '• Example #1'
#3: • Commentary #2
и из
••var_1 = "var_2 = \"• Don't cry...\" + 'Why?';" + var_2• Commentary #1 ••
в
#1: 2
#2: var_1 = "var_2 = \"• Don't cry...\" + 'Why?';" + var_2
#3: • Commentary #1 ••

Большое спасибо!

x-yuri 18.10.2009 23:39

Цитата:

Сообщение от Paguo-86PK
Как здесь нужно описать регулярое выражение, чтобы выловить и тэг URL, и location, и Hint, и Address?

ваш неработающий вариант?

Цитата:

Сообщение от Paguo-86PK
Могут ли и тут помочь регулярки?

могут

Paguo-86PK 19.10.2009 01:15

Вариант - позор джунглей
 
Цитата:

Сообщение от x-yuri (Сообщение 32714)
ваш неработающий вариант?
могут

Понимаю, понимаю.
Но вариантов нет. Сутки вожусь, а споткнулся на
<html><head><title>Parser is easy!</title><script>
window.onload = function() {
 html = new Array();
 text = "•••txt = \"Text•1\" + 'Text•2'•Commentary";
 tabs = text.search(/[^•]/g); // Считаем число вступительных
 html.push("......".substr(0, tabs)); // и выводим как точки
 text = text.substr(tabs); // Исключаем эти знаки из начала
 len = text.search(/[^[\x22*•*\x22]^[\x27*•*\x27]]/g);
 html.push(len + text.substr(0, len)); // Возвращается -1
 document.write("<pre>" + html.join("<br/>") + "</pre>");
}
</script></head>
<body>
</body>
</html>

x-yuri 19.10.2009 01:28

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

Paguo-86PK 19.10.2009 01:38

А можно поподробнее? Я понимаю, время - деньги. Мой вариант
len = text.search(/^(\x22*•*\x22)^(\x27*•*\x27)/g);
стал выдавать 0, вместо -1.
А мне нужно - начало комментариев. Т.е. 25

x-yuri 19.10.2009 01:51

/(•*)(([^•"']|("|')[^\4]*\4)*)(.*)/

Paguo-86PK 19.10.2009 02:36

Вопросов больше, чем ожидал
 
Спасибо большое!
Не ожидал. Это заменяет почти 20 строк моего скрипта!
Только я не понял назначение \4 два раза и почему возвращается массив
  • •••txt = "Text•1" + 'Text•2'•Commentary
  • •••
  • txt = "Text•1" + 'Text•2'
  • 'Text•2'
  • '
  • •Commentary
Где элементы 3 и 4 лишние. Это нормально и мне следует использовать элементы 1, 2 и 5? Или глюк, который можно обойти?

x-yuri 19.10.2009 03:01

\n (http://javascript.ru/RegExp)

Цитата:

Сообщение от Paguo-86PK
Это нормально и мне следует использовать элементы 1, 2 и 5?

нормально, возвращается вся строка и все подшаблоны (x)

Paguo-86PK 19.10.2009 03:26

Всё равно материал по регуляркам не исчерпывающий
 
В первом посту я указал, что я по той ссылке бродил...;)
Однако глюк и сильный есть: Если в комментарий поместить " или ', он перестаёт быть комментарием:blink:Даже ошибку выдаёт:-?
Даже не знаю, можно ли устранить...
На всякий случай даю код
<html><head><title>Parser is easy!</title><script>
function Parse(text) {
 html = new Array();
 rgl = /(•*)(([^•"']|("|')[^\4]*\4)*)(.*)/;
 line = rgl.exec(text);
 try {
  for(i = 0; i < line.length; ++ i)
   switch(i) {
   case 0: case 3: case 4: // "Лишние" элементы зачёркиваем, делая тусклыми
    html.push(line[i].strike().fontcolor("gray"));
    break;
   case 2:                 // Основное выражение выделяем
    html.push(line[i].bold());
    break;
   case 5:                 // Зелёный комментарий курсивом
    html.push(line[i].italics().fontcolor("green"));
    break;
   default:
    html.push(line[i]);
    break;
   }
 }
 catch(e) {
  html.push("i = " + i + " is " + e);
 }
 document.getElementById("Log").innerHTML = html.join("<br/>");
}
</script></head>
<body>
<textarea rows="12" cols="80" onkeyup="Parse(this.value)">•••txt = "Text•1" + 'Text•2'•Commentary</textarea>
<pre id="Log"></pre>
</body>
</html>

x-yuri 19.10.2009 03:48

Цитата:

Сообщение от Paguo-86PK
В первом посту я указал, что я по той ссылке бродил...

так вы спрашивайте, что непонятно

Цитата:

Сообщение от Paguo-86PK
Если в комментарий поместить " или ', он перестаёт быть комментарием

да, это связано с тем, что квантификаторы по умолчанию жадные. Можно почитать в строке с ?


Часовой пояс GMT +3, время: 02:26.