Javascript正则表达式多行标志不起作用

259 javascript regex

我写了一个正则表达式来从html中获取字符串,但似乎多行标志不起作用.

这是我的模式,我想在h1标签中获取文本.

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

我创建了一个字符串来测试它.当字符串包含"\n"时,结果始终为null.如果我删除所有"\n",它给了我正确的结果,无论是否带有/ m标志.

我的正则表达式有什么问题?

mol*_*olf 597

您正在寻找/.../s修饰符,也称为dotall修饰符.它强制点.也匹配换行符,默认情况下不会这样做.

坏消息是它在JavaScript中不存在 (从ES2018开始,见下文).好消息是你可以通过使用一个字符类(例如\s)和它的否定(\S)来解决它,就像这样:

[\s\S]
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,正则表达式将成为:

/<div class="box-content-5">[\s\S]*<h1>([^<]+?)<\/h1>/i
Run Code Online (Sandbox Code Playgroud)

从ES2018开始,JavaScript支持s(dotAll)标志,所以在现代环境中,你的正则表达式可能就像你编写它一样,但最后有一个s标志(而不是m; m改变方式^$工作,而不是.):

/<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/is
Run Code Online (Sandbox Code Playgroud)

  • 作为替代方案的[\ s\S] +1,没有想到这一点 (67认同)
  • 根据MDN,`[^]`也适用于匹配JavaScript中的任何字符,包括换行符.请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#character-classes (38认同)
  • [^]版本在regexp编译器上更容易,也更简洁. (9认同)
  • 对于性能问题,强烈建议使用`*?`量词而不是`*`以避免贪婪.这将避免捕获文档的**最后**<h1>:这可能不是你想要的那样,并且效率不高,因为正则表达式将继续寻找<h1>直到字符串结尾,即使它已经找到它之前. (6认同)
  • @simo匹配任何空格或非空格字符,有效匹配任何字符.它就像`.`,但匹配的空格(`\ s`)意味着它匹配`\n`(`.`在JavaScript中不起作用,或者可以与`s`标志一起使用). (5认同)
  • `[^]` 仅适用于 JavaScript(和其他 ECMAScript 实现),如果您尝试在其他风格中使用它,可能会产生意想不到的结果。 (2认同)

Gre*_*reg 20

你想要s(dotall)修饰符,它显然在Javascript中不存在 - 你可以用.@molf建议的[\ s\S]替换.的m(多)修饰符使得^和$匹配行,而不是整个字符串.

  • 您可以添加/ s"修饰符设置单线模式而不是多线模式.+ 1 (4认同)

小智 12

[\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次或更多次[^]的非贪婪抓取.


For*_*vin 7

dotall修饰符实际上已于2018年6月成为JavaScript,即ECMAScript 2018.https
://github.com/tc39/proposal-regexp-dotall-flag

const re = /foo.bar/s; // Or, `const re = new RegExp('foo.bar', 's');`.
re.test('foo\nbar');
// ? true
re.dotAll
// ? true
re.flags
// ? 's'
Run Code Online (Sandbox Code Playgroud)