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

cczfrluj  于 2023-01-04  发布在  Java
关注(0)|答案(8)|浏览(124)
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr);     // null

我希望PRE块被选中,即使它跨越了换行符。我认为'm'标志可以。
在发帖前找到了答案here。因为我认为我了解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的悲哀之处之一。

sqougxex

sqougxex1#

不要使用(.|[\r\n])代替.进行多行匹配。
对于多行匹配,请使用[\s\S]而不是.
此外,通过使用*?+?量词而不是*+,避免不需要的贪婪。这可能会对性能产生巨大影响。
看看我做的基准:https://jsben.ch/R4Hxu

Using [^]: fastest
Using [\s\S]: 0.83% slower
Using (.|\r|\n): 96% slower
Using (.|[\r\n]): 96% slower

注意:您也可以使用[^],但在下面的注解中已弃用。

06odsfpq

06odsfpq2#

[.\n]不起作用,因为.[]中没有特殊含义,它只是表示一个文字.(.|\n)可以指定"任意字符,包括换行符"。如果您想匹配所有换行符,您还需要添加\r以包括Windows和经典Mac OS风格的行尾:(.|[\r\n]).
结果证明这有点麻烦,而且速度慢(参见KrisWebDev's answer for details),所以更好的方法是用[\s\S]匹配所有空格字符和所有非空格字符,[\s\S]可以匹配所有字符,而且更快更简单。
一般来说,你不应该尝试使用正则表达式来匹配实际的HTML标记,例如,参见these问题,了解更多关于为什么的信息。
相反,尝试实际搜索DOM以查找所需的标记(使用jQuery会使这一过程更容易,但您始终可以使用标准DOM执行document.getElementsByTagName("pre")),然后如果需要与内容进行匹配,则使用regexp搜索这些结果的文本内容。

xxb16uws

xxb16uws3#

你不需要指定你的环境和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

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

pengsaosao

pengsaosao4#

现在有了s(单行)修饰符,它让点也匹配新行:)\s也将匹配新行:D
只要在斜线后面加上s

/<pre>.*?<\/pre>/gms
xmakbtuz

xmakbtuz5#

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

iyfjxgzm

iyfjxgzm6#

我已经测试过它(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
e5njpo68

e5njpo687#

除上述例子外,它是一种替代方法。

^[\\w\\s]*$

其中\w表示单词,\s白色

4c8rllxm

4c8rllxm8#

第一个月
这一个对我来说是非常有帮助的,特别是对于匹配多个东西,包括新行,每一个单一的其他答案最终只是分组所有的匹配在一起。

相关问题