Регулярное выражение для вложенных значений - PullRequest
2 голосов
/ 19 марта 2011

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

Я имею в виду, например, это:

/*asdasdasd /* asdasdsa */ qweqweqwe */

для сопоставления первого "/ *" с последним "* /"и не останавливаясь на первом" * / "

Спасибо ...

Ответы [ 5 ]

3 голосов
/ 19 марта 2011

Регулярные выражения не могут считать вложенные элементы по определению (хотя реализации идут дальше, чем компьютерное научное определение).

См. http://en.wikipedia.org/wiki/Regular_expression#Expressive_power_and_compactness

3 голосов
/ 19 марта 2011

Выражения RegEx естественно будут жадными, поэтому вы можете просто использовать:

\/\*.*\*\/

Если вы хотите, чтобы он сделал то, чего вы боитесь, и RegEx будет ленивым и остановится после первого матча, вам нужно будет добавить ? вроде:

\/\*.*?\*\/
1 голос
/ 19 марта 2011

Представленные решения работают нормально, если в тексте есть только один вложенный комментарий.Однако, как отметил LHMathies, если текст содержит более одного комментария с вещами, которые вы хотите оставить между ними, то эти решения не сработают.Например, вот некоторые тестовые данные для проверки правильности работы алгоритма:

/* one */
Stuff one
/* two /* three */ two */
Stuff two
/* four */

Правильное решение сохранит две строки с содержимым в них.Чтобы правильно обработать этот случай в Javascript, вам нужно регулярное выражение, соответствующее внутреннему комментарию (и это сложная часть), а затем применять его несколько раз, пока все комментарии не исчезнут.Вот протестированная функция, которая делает именно это:

function strip_nested_C_comments(text)
{ // Regex to match innermost "C" style comment.
    var re = /\/\*[^*\/]*(?:(?!\/\*|\*\/)[*\/][^*\/]*)*\*\//i;
    // Iterate stripping comments from inside out.
    while (text.search(re) != -1) {
        text = text.replace(re, '');
    }
    return text;
}

Редактировать: Улучшена эффективность регулярных выражений для несоответствующих случаев.(то есть изменил «специальный» с [\S\s] на [*\/]).

0 голосов
/ 19 марта 2011

Я предполагаю, что вам действительно нужно что-то, что удалит или обработает правильно вложенные комментарии из строки, даже если их больше одного - ответы, дающие «жадные» регулярные выражения, будут идти от первых /* кпоследний */: в таких строках, как keep /* comment */ keep /* comment */ keep, они будут обрабатывать середину keep как часть комментария.

Короткий ответ: Javascript RegExps недостаточно мощен, чтобы сделать это, вам нужнорекурсивные паттерны.(Также известный как регулярные выражения не могут считать ).

Но, если вы просто хотите удалить комментарии, вы можете сначала использовать цикл и удалить самые внутренние комментарии (используя неgreedy RegExp из @mVChr, измененный, чтобы соответствовать последнему возможному начальному разделителю вместо первого):

var re = /(.*)\/\*.*?\*\//; while (re.test(string)) string.replace(re, '$1')

Это перемещает подсчет (уровней вложенности) из регулярного выражения и, так сказать, в цикл,(Я не поставил флаг g в регулярном выражении, потому что я не уверен в побочных эффектах при использовании такого регулярного выражения в двух местах цикла. И цикл все равно заботится о нахождении всех вхождений).

0 голосов
/ 19 марта 2011

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

Но регулярные выражения естественно жадные. Это означает, что квантификаторы * и + по умолчанию будут выполнять именно то, что вы просите

var data = "/*asdasdasd /* asdasdsa */ qweqweqwe */";
data = data.replace( /\/\*.*\*\//, '' );
alert( 'Data: ' + data );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...