如何在多行上使用JavaScript正则表达式?

aka*_*ppi 248 javascript regex

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr);     // null
Run Code Online (Sandbox Code Playgroud)

我想要接收PRE块,即使它跨越换行符.我以为'米'旗就是这么做的.才不是.

找到答案在这里发布之前.我以为我认识JavaScript(读了三本书,工作了几个小时),而且现在没有现成的解决方案,我敢于发帖.在这里扔石头

所以解决方案是:

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr);     // <pre>...</pre> :)
Run Code Online (Sandbox Code Playgroud)

有人有一个不那么神秘的方式吗?

编辑:是一个副本,但因为它比我的更难找到,我不删除.

它建议[^]作为"多线点".我仍然不明白为什么[.\n]不起作用.猜猜这是JavaScript的悲伤部分之一..

Kri*_*Dev 313

不要使用(.|[\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
Run Code Online (Sandbox Code Playgroud)

注意:您也可以使用,[^]但在以下评论中已弃用.

  • 好点,但我建议不要使用`[^]`.一方面,JavaScript是我所知道的唯一支持这种习语的风格,即便在那里使用它的频率远远超过`[\ s\S]`.另一方面,大多数其他风格让你首先列出它来逃避`]`.换句话说,在JavaScript中,`[^] [^]`匹配任意两个字符,但在.NET中,它匹配除```,`[`或`^`之外的任何*one*字符. (20认同)
  • 有关\ s\S的详细信息,请参阅[此问题](http://stackoverflow.com/questions/4544636/what-does-ss-mean-in-regex-in-php).这是一个匹配所有空白字符+所有非空白字符=所有字符的黑客.另请参阅[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)以获取正则表达式特殊字符文档. (3认同)
  • 有没有理由比其他人更喜欢`[\ s\S]`,比如`[\ d\D]`或`[\ w\W]`? (3认同)
  • 你怎么知道 `\S` 会匹配 `\r` 或 `\n` 与其他一些字符? (2认同)

Bri*_*ell 219

[.\n]不起作用,因为.里面没有特殊意义[],它只是意味着文字..(.|\n)将是一种指定"任何字符,包括换行符"的方法.如果您想匹配所有换行符,您还需要添加\r以包含Windows和经典Mac OS样式行结尾:(.|[\r\n]).

事实证明这有点麻烦,而且速度慢(请参阅KrisWebDev的详细解答),所以更好的方法是匹配所有空白字符和所有非空白字符[\s\S],它们将匹配所有内容,并且更快,简单.

通常,您不应该尝试使用正则表达式来匹配实际的HTML标记.例如,请参阅这些 问题以获取有关原因的更多信息.

相反,尝试实际搜索DOM以获取所需的标记(使用jQuery使这更容易,但您可以document.getElementsByTagName("pre")使用标准DOM),然后如果需要匹配内容,则使用正则表达式搜索这些结果的文本内容.

  • 要匹配_整个_多行字符串,请尝试使用贪婪的 `[\s\S]+`。 (3认同)
  • `[\r\n]`应用于序列\r\n,将首先匹配\r,然后匹配\n。如果您想一次匹配整个序列,无论该序列是\r\n 还是只是\n,请使用模式`.|\r?\n` (2认同)

Hus*_*012 20

现在有 s(单行)修饰符,它可以让点也匹配新行:) \s 也将匹配新行:D

只需在斜杠后面添加 s 即可

 /<pre>.*?<\/pre>/gms
Run Code Online (Sandbox Code Playgroud)


Nee*_*eek 16

你没有指定你的环境和Javascript版本(ECMAscript),我发现这篇文章是从2009年开始的,但为了完整起见,随着ECMA2018的发布,我们现在可以使用该s标志.来匹配'\n',请参阅https ://stackoverflow.com/a/36006948/141801

从而:

let s = 'I am a string\nover several\nlines.';
console.log('String: "' + s + '".');

let r = /string.*several.*lines/s; // Note 's' modifier
console.log('Match? ' + r.test(s); // 'test' returns true
Run Code Online (Sandbox Code Playgroud)

这是最近添加的,并且在许多当前环境中都不起作用,例如Node v8.7.0似乎无法识别它,但它在Chromium中工作,我在我正在编写的Typescript测试中使用它,并且可能是它随着时间的推移,它将变得更加主流.

  • 这在 Chrome (v67) 中效果很好,但在 IE11 和 IEdge(v42) 中完全破坏了正则表达式(也停止逐行工作) (3认同)

Y. *_*ham 11

[.\n]不起作用,因为dot in [](通过正则表达式定义;不仅仅是javascript)表示点字符.您可以使用(.|\n)(或(.|[\n\r]))代替.

  • `[\ s\S]`是用于匹配包括换行符在内的所有内容的最常见的JavaScript习惯用法.它比眼睛更容易,比基于交替的方法更有效,比如`(.| \n)`.(它的字面意思是"*是*空格的任何字符或*不是*空格的任何字符.) (23认同)
  • 你是对的,但问题是关于`.`和`\n`,以及为什么`[.\n]`不起作用.正如问题所述,`[^]`也是很好的方法. (2认同)

Khu*_*Ran 7

我测试了它(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
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

152062 次

最近记录:

7 年,5 月 前