Как использовать регулярное выражение JavaScript для нескольких строк?
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr); // null
Я бы хотел, чтобы блок PRE был поднят, хотя он охватывает символы новой строки. Я думал, что флаг "m" делает это. Не делает.
Найден ответ здесь перед публикацией. SInce Я думал, что знаю JavaScript (читал три книги, работал часов), и в SO не было никакого решения, я все равно осмелюсь публиковать. бросать камни здесь
Итак, решение:
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr); // <pre>...</pre> :)
Есть ли у кого-нибудь менее загадочный способ?
Изменить: this является дубликатом, но, поскольку его сложнее найти, чем у меня, я не удаляю.
Он предлагает [^]
как "многострочную точку". Я все еще не понимаю, почему [.\n]
не работает. Угадайте, что это одна из грустных частей JavaScript.
Ответы
Ответ 1
[.\n]
не работает, потому что .
не имеет особого значения внутри []
, это просто означает литерал .
. (.|\n)
- это способ указать "любой символ, включая новую строку". Если вы хотите совместить все новые строки, вам нужно будет добавить \r
, чтобы включить окончание строк стиля Windows и классического Mac OS: (.|[\r\n])
.
Это оказывается несколько громоздким, а также медленным (см. ответ KrisWebDev для деталей), поэтому лучшим подходом было бы сопоставление всех символов пробелов и все символы без пробелов, с [\s\S]
, которые будут соответствовать всем, и быстрее и проще.
В общем, вы не должны пытаться использовать регулярное выражение для соответствия фактическим тегам HTML. См., Например, эти questions для получения дополнительной информации о том, почему.
Вместо этого попробуйте выполнить поиск DOM в нужном вам теге (использование jQuery делает это проще, но вы всегда можете сделать document.getElementsByTagName("pre")
со стандартным DOM), а затем искать текстовое содержимое этих результатов с помощью регулярного выражения, если вы необходимо сопоставить с содержимым.
Ответ 2
НЕ используйте (.|[\r\n])
вместо .
для многострочного сопоставления.
Используйте [\s\S]
вместо .
для многострочного соответствия
Также избегайте жадности, если это не нужно, используя квантор *?
или +?
вместо *
или +
. Это может иметь огромное влияние на производительность.
См. контрольный показатель, который я сделал: http://jsperf.com/javascript-multiline-regexp-workarounds
Using [^]: fastest
Using [\s\S]: 0.83% slower
Using (.|\r|\n): 96% slower
Using (.|[\r\n]): 96% slower
Примечание. Вы также можете использовать [^]
, но в приведенном ниже комментариях он устарел.
Ответ 3
[.\n]
не работает, потому что точка в []
(по определению regex, а не только по javascript) означает dot-character. Вместо этого вы можете использовать (.|\n)
(или (.|[\n\r])
).
Ответ 4
Я тестировал его (Chrome), и он работает для меня (как [^]
и [^\0]
), меняя точку (.
) на [^\0]
или [^]
, потому что точка не (см. здесь http://www.regular-expressions.info/dot.html).
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[^\0]*?<\/pre>/gm );
alert(arr); //Working