2013-06-24 2 views
0

Как я могу получить все совпадения для [.*], но нет, если скобки имеют обратную косую черту как \[.*\]?Regex соответствует [], но не []

Я могу использовать функцию JavaScript new RegExp("\\[.*\\]", "g"), чтобы получить все [.*]. Как я могу исключить все \[.*\] (экранированные скобки)?

ввода выглядит следующим образом:

div\[data-custom-attribute='References'\][matchme] 

В этом случае регулярное выражение должно соответствовать [matchme].

+1

Почему бы не использовать литералы регулярных выражений, чтобы создать регулярное выражение, чтобы избежать двойного выхода из обратных косых черт? '/\[.*\]/ g' – hugomg

ответ

1

http://rubular.com/r/16q3jSPHN0

[^\\](?:\]?(\[(.+?)\])) должны работать в большинстве случаев.

Edit:

Похоже, что это не будет соответствовать \[test\][test] как Рори указал. Для этого, я не могу думать о хорошем решения без использования нескольких регэкспы, но если вы хотите просто один попробуйте это: http://rubular.com/r/QBqFAbqW9E

(?:[^\\](?:\]?(\[(.+?)\]))|((?:\]?(\[(.+?)\])))\\)

матч группы будут заполнены в первом 3, если он имеет блок с экранированными скобками, после - обычный блок, а последние 3 - если происходит противоположное.

Match 1 
1. 
2. 
3. [test] 
4. [test] 
5. test 
Match 2 
1. [test] 
2. test 
3. 
4. 
5. 
+1

JavaScript [не поддерживается] (http://www.regular-expressions.info/javascript.html) [lookbehind] (http://www.regular-expressions.info /lookaround.html), так что это лучшее, что вы можете сделать. Но если бы JavaScript сделал, было бы лучше заменить '[^ \\]' на '(?

+0

@ RoryO'Kane ах ты прав. Я думаю, было бы разумно использовать два выражения: по одному для каждого случая, по крайней мере, в отношении JS. В качестве альтернативы, я обновил свой комментарий одним выражением, которое, похоже, улавливает оба случая, но оно вытесняет сгруппированные результаты в зависимости от положения экранированных блоков. Не могу придумать лучшего решения. – dav

+0

Почему ваши тестовые строки не содержат никаких обратных косых черт? Единственная обратная косая черта в строке ускользает от следующего символа (если что-либо), поэтому ваши одиночные обратные косые черты фактически не являются частью строки, что означает, что вы не проверяете данные точно. В реальном примере ваше первое регулярное выражение не работает: http://jsfiddle.net/A6XBH/1/ – Ian

0

использовать не catchable группа, как [^\\]:

[^\\]\[.*[^\\]\] 
+2

Я думаю, что фраза, которую вы ищете, - это * не захватывающая * группа, но то, что у вас есть, на самом деле является отрицательным символьным классом, и это не решает проблему. Во-первых, ваше регулярное выражение не будет соответствовать '[test]' в начале строки, потому что оно должно потреблять символ перед открытием '['. Возможно, вы думаете о негативном образе, но JavaScript не поддерживает их. –

+0

Mmmh ... Совершенно верно, спасибо за эти замечания! – zessx

1

Самая большая проблема зная, что вы смотрите на сбежавшего кронштейне (\[) или кронштейн, который следует сбежавшего обратной косой черты (\\[). Это достаточно просто, если вы ищете только для одного матча:

/^[^\]\[\\]*(?:\\.[^\]\[\\]*)*(\[[^\]\[]+\])/ 

Первая часть проглатывает любые другие, чем обратные косая черта или квадратные скобки символов. Если он видит обратную косую черту, он захватывает это и следующий символ, каким бы он ни был. Он повторяет этот процесс столько раз, сколько может, и когда он больше не может этого сделать, следующая вещь должна быть заключенной в квадратные скобки (или «тегом»), которую вы ищете. Он зафиксирован в группе №1.

Получение остальных тегов сложнее. Чтобы оставаться в синхронизации с данными, вы хотите, чтобы каждое последующее совпадение начиналось точно там, где предыдущий матч остался. Многие ароматы регулярных выражений поддерживают якорь \G для этой цели, но это нам не помогает. JavaScript находится в процессе принятия флага /y, что делает практически то же самое, но пока вы не можете рассчитывать на это.

Вот обходной путь, который должен работать в случае:

/(?:^|\[[^\]\[]+\])[^\]\[\\]*(?:\\.[^\]\[\\]*)*(?=(\[[^\]\[]+\]))/g 

Ядро регулярное выражение то же самое, но группа захвата теперь внутри опережающего просмотра. В первый раз он начинает сопоставляться в начале строки, как и раньше, но он останавливается чуть ниже первого тега.Взгляд подтверждает, что тег присутствует, но не потребляет его. Следующий матч начинается с повторного сопоставления тега, на этот раз его потребляя. Между тем, тег также фиксируется в группе №1, поэтому вы можете получить к нему доступ обычным способом.

var regex = /(?:^|\[[^\]\[]+\])[^\]\[\\]*(?:\\.[^\]\[\\]*)*(?=(\[[^\]\[]+\]))/g; 
var match = regex.exec(subject); 
while (match != null) { 
    // tag is in match[1] 
    match = regex.exec(subject); 
} 
Смежные вопросы