Многострочный флаг регулярных выражений Javascript не работает

222

Я написал регулярное выражение для извлечения строки из html, но кажется, что многострочный флаг не работает.

это мой шаблон, и я хочу получить текст в теге h1.

var pattern= /<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/mi
m = html.search(pattern);
return m[1];

Я создал строку для ее проверки. Когда строка содержит "\n", результат всегда равен нулю. Если я удалю все "\n", это дало мне правильный результат, независимо от флага/или без него.

что не так с моим регулярным выражением?

  • 14
    Не используйте регулярные выражения для разбора HTML, HTML НЕ является обычным языком. Используйте анализатор HTML, соответственно ДОМ. Это также намного проще.
  • 0
    Вы ищете DOTALL, а не многострочный.
Показать ещё 1 комментарий
Теги:

4 ответа

507
Лучший ответ

Вы ищете модификатор /.../s, также известный как модификатор dotall. Это заставляет точку . также соответствовать новым строкам, которые по умолчанию не выполняются.

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

[\s\S]

Итак, в вашем случае регулярное выражение станет следующим:

/<div class="box-content-5">[\s\S]*<h1>([^<]+?)<\/h1>/i
  • 65
    +1 за [\ s \ S] как альтернативу, не подумал об этом
  • 0
    Черт! И какова логика [\s\S]* ?!?!
Показать ещё 7 комментариев
21

Вам нужен модификатор s (dotall), который, по-видимому, не существует в Javascript - вы можете заменить . на [\ s\S], как это было предложено @molf. Модификатор m (multiline) делает строки $и $, а не целую строку.

  • 4
    Вы можете добавить, что модификатор / s устанавливает однострочный режим, а не многострочный. +1
  • 0
    Девять лет спустя JavaScript теперь имеет флаг s (ES2018). :-)
3

Модификатор dotall действительно может превратить его в JavaScript в ближайшее время. https://github.com/tc39/proposal-regexp-dotall-flag

Возможно, в ECMAScript 2018, увидев, что он находится на этапе 3 процесса TC39.

1

[\s\S] не работал у меня в nodejs 6.11.3. Основываясь на документации RegExp, он говорит, что использует [^], который работает для меня.

(Точка, десятичная точка) соответствует любому одиночному символу, кроме строки терминаторы:\n,\r,\u2028 или \u2029.

Внутри набора символов точка теряет свое особое значение и соответствует буквальная точка.

Обратите внимание, что m многострочный флаг не изменяет поведение точки. Итак, чтобы сопоставить шаблон по нескольким строкам, набор символов [^] может быть (если вы не имеете в виду старую версию IE, конечно), это будет соответствует любому символу, включая символы новой строки.

Например:

/This is on line 1[^]*?This is on line 3/m

где *? является не-жадным захватом 0 или более вхождений [^].

  • 0
    То же самое в узле 8.10 - работает только [^], а не [\ s \ S].
  • 1
    Для тех, кто задается вопросом, что означает [^] : это похоже на двойное отрицание: «соответствовать любому символу, которого нет в этом пустом списке», и поэтому все сводится к высказыванию «соответствует любому символу» .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню