Самая большая проблема заключается в том, чтобы понять, смотрите ли вы на экранированную скобку (\[
) или на скобку, которая следует за экранированной обратной косой чертой (\\[
). Это достаточно просто, если вы ищете только одно совпадение:
/^[^\]\[\\]*(?:\\.[^\]\[\\]*)*(\[[^\]\[]+\])/
Первая часть поглощает любые символы, кроме обратной косой черты или квадратных скобок. Если он видит обратную косую черту, он захватывает его и следующий символ, каким бы он ни был. Он повторяет этот процесс столько раз, сколько может, и когда он больше не может этого делать, следующей вещью должно быть значение в квадратных скобках (или «тег»), которое вы ищете. Он захвачен в группе №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);
}
person
Alan Moore
schedule
24.06.2013
/\[.*\]/g
- person hugomg   schedule 24.06.2013