2010-12-11 4 views
12

Пример строки: $${a},{s$${d}$$}$$Рекурсивный соответствие с регулярными выражениями в JavaScript

Я хотел бы, чтобы соответствовать $${d}$$ первым и заменить его какой-нибудь текст, так что строка станет $${a},{sd}$$, то $${a},{sd}$$ будет сравниваться.

+2

не могли бы вы просто использовать два отдельных регулярных выражений? Сначала встретите №1, замените, а затем попытайтесь совместить # 2? – Pandincus

+0

@Pandincus: Это не позволит гнездиться, иначе да. – Orbling

ответ

21

Раздражающе, Javascript не предоставляет рекурсивный параметр PCRE (?R), поэтому далеко нелегко справиться с вложенной проблемой. Однако это можно сделать.

Я не буду воспроизводить код, но если вы зарегистрируетесь Steve Levithan's blog, у него есть хорошие статьи по этому вопросу. Он должен это сделать, он, вероятно, является ведущим авторитетом в RegExp в JS. Он написал XRegExp, который заменяет большинство бит PCRE, которые отсутствуют, есть даже плагин Match Recursive!

+1

+1 очень полезные ссылки – bowsersenior

+0

Я бы не сказал, что XRegExp заменяет «большинство недостающих частей», но *** помогает ***. Однако для реальных регулярных выражений вам нужна полная поддержка свойств и графем. Более 80% Интернета - это Unicode, и это преступление, с которым вы не можете справиться с ним в браузере. – tchrist

+0

@tchrist: Англоговорящий мир едва использует его, поэтому он не имеет значения для людей, которые могут его изменить. То, что добавлено к принципу невероятно медленного изменения базового уровня сети, делает такие вещи еще далеко. Неудобно сказать меньше всего. – Orbling

0

В общем, регулярные выражения не очень подходят для такого рода проблем. Лучше использовать конечный автомат.

+0

Возможно, парсер? – Orbling

+0

@Orbling: http://pegjs.majda.cz/ Это выглядит интересно :-P – Pandincus

+0

@Pandincus: Nice, yacc для JS. :-) – Orbling

1

Поскольку вы хотите сделать это рекурсивно, вам, вероятно, лучше всего делать несколько совпадений, используя цикл.

Regex сам по себе не подходит для рекурсивного-ничего.

0

Я написал это сам:

String.prototype.replacerec = function (pattern, what) { 
    var newstr = this.replace(pattern, what); 
    if (newstr == this) 
     return newstr; 
    return newstr.replace(pattern, what); 
}; 

Использование:

"My text".replacerec(/pattern/g,"what"); 
+1

Я использовал его в производственном коде, работающем более года. Это редкий шанс, что регулярное выражение продолжает соответствовать бесконечным временам. Так что никакого переполнения! И это быстрый способ получить рекурсивную замену прямо из кода JavaScript. –

+0

Предел стека не бесконечен. IE6 может обрабатывать только 1130 вызовов. Это не 1130 регулярных выражений, это общее количество регулярных выражений плюс все, что у вас есть. Сказать, что это достаточно хороший ответ, неверен, потому что кто-то может использовать его в уже интенсивно функционирующей среде, и что-то, что не следует добавлять в стек, может привести к переполнению. Таким образом, 1. – lededje

0
var content = "your string content"; 
var found = true; 
while (found) { 
    found = false; 
    content = content.replace(/regex/,() => { found = true; return "new value"; }); 
} 
+0

Хотя концепции, возможно, есть, есть так много, что не будет работать, может пойти очень неправильно и не решает вопрос. –

+0

Что может пойти не так? Этот простой шаблон может решить проблему в вопросе с помощью правильного определения регулярного выражения. –

+0

Он не имеет резервной копии, поэтому, если он не соответствует, он, вероятно, превысит допустимый объем памяти. И что такое «новая ценность» и откуда оно взяться? И вы не показываете, как регулярное выражение OP действительно может работать в этом коде. –