javascript正则中使用[\s\S]*用来匹配任意字符(包括换行符)的方法不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript正则中使用[\s\S]*用来匹配任意字符(包括换行符)的方法不起作用相关的知识,希望对你有一定的参考价值。

例如下面是匹配test.html页面中的body内容,如果不把内容中的换行符去掉,匹配不到内容。
但如果用[\s\S]*的方法来匹配任意字符,在js里还不起作用。
请问在js中有什么方法匹配任意字符,包括换行。

<script type="text/javascript">
// 需要引入jQuery
$.get("test.html",function(html)
//html = html.replace(/[\r\n]+/g,''); // 需要把换行符替换掉,下面的正则才能匹配到内容
var bodyPat = new RegExp('<body[^>]*>(.*?)<\/body>','i');
var matchArr = html.match(bodyPat);
console.dir(matchArr);
);
</script>

正则表达式可以用.*匹配任意除换行之外的字符。但如果内容中包含任意多个换行怎么匹配?用.*是匹配失败的。但可以用[\\s\\S]*?。
\\s是匹配所有空白字符,\\S是匹配所有非空白字符,那么[\\s\\S]这个组合就可以匹配所有字符了。
但是换行符是匹配不到的:

//-- 通过正则表达式来替换换行符
var regRN = /\\r\\n/g;
str = str.replace(regRN,"<br />");

//-- 其他场景(分别替换\\r和\\n)
var regR = /\\r/g;
var regN = /\\n/g;
str = str.replace(regR,"\\\\r").replace(regN,"\\\\n");
参考技术A

用来匹配任意字符的,你完全可以不用[\\s\\S]的,直接用 '.' 就可以了!

var a = 'asdfsdfsdfsdfs\\nasdfwefsadfasdfsdfsadfs';
var b = a.replace(/./g,'3');
alert(b);   //这样就可以了。
如果你想替换回车,可以用[\\w\\W] 或者[\\s\\S], 这个g是不可以省略的。
var a = 'asdfsdfsdfsdfs\\nasdfwefsadfasdfsdfsadfs';
var b = a.replace(/[\\w\\W] /g,'3');
alert(b);   //这样就可以了。

参考技术B var bodyPat = new RegExp('<body[^>]*>([\\\\s\\\\S]*?)<\\\\/body>','i');

new RegExp的时候用两个斜杠


如果没有字符串链接,直接用下面的

var bodyPat = /<body[^>]*>([\\s\\S]*?)<\\/body>/i;

本回答被提问者采纳
参考技术C var bodyPat = new RegExp('<body[^>]*>(.*?)<\\/body>','im');

试一下,其他不要该。

追问

不行的,添加多行修正符m也不行。
将(.*?)换成([\s\S]*?)也不行。

参考技术D 需要用到单行模式,你百度一下,单行模式下面 .*号可以匹配换行符

Javascript 替代品中的正则表达式 Lookbehind

【中文标题】Javascript 替代品中的正则表达式 Lookbehind【英文标题】:Regex Lookbehind in Javascript Alternatives 【发布时间】:2019-01-18 11:41:09 【问题描述】:

我正在尝试在 JS 中使用以下正则表达式:

(?&lt;=@[A-Z|a-z]+,)\s|(?&lt;=@[A-Z|a-z]+,\s[A-Z|a-z]+)\s(?=\[[A-Z|a-z]+\])

翻译成:

匹配所有以 : 开头的空格

@ 后跟A-Za-z 范围内的任意数量的字符 后跟逗号

匹配前面的所有空格:

@

后跟A-Za-z 范围内的任意数量的字符

后跟逗号 后跟一个空格 后跟A-Za-z 范围内的任意数量的字符

AND 成功:

[ 后跟A-Za-z 范围内的任意数量的字符 ]

但是,JS 不支持lookbehind。是否有任何替代方法可以在 JS 或任何我可以使用的 npm 库中支持上述正则表达式?

所以,如果我们有一个像Hi my name is @John, Doe [Example] and I am happy to be here 这样的句子应该变成Hi my name is @John,Doe[Example] and I am happy to be here。 另外,如果我们有类似Hi my name is @John, Smith Doe [Example] 之类的东西,那应该变成Hi my name is @John,SmithDoe[Example]

【问题讨论】:

JavaScript 确实支持后视,从 ECMAScript 2018 开始。但几乎没有浏览器支持。 你想替换什么东西吗? @revo 试图替换那些空格,是的 将您的lookbehinds转换为捕获组,并在进行替换时为它们添加反向引用以使它们出现在结果中。 @revo 您能否发布一个示例作为答案 - 不完全确定如何做到这一点 【参考方案1】:

我已经根据新的输入更新了我的答案

console.clear();

var inputEl = document.querySelector('#input')
var outputEl = document.querySelector('#output')

function rep (e) 
  var input = e.target.value;
  var reg = /@([a-z]+?\s*?)+,(\s+[a-z]+)+(\s\[[a-z]+\])?/gim



  matches = input.match(reg);
  var output = input;

  if (matches) 
    replaceMap = new Map()
    for (var i = 0; i < matches.length; i++) 
      var m = matches[i]
        .replace(/\[/, '\\[')
        .replace(/\]/, '\\]')
      replaceMap.set(m, matches[i].replace(/\s+/gm, ''))
    
    for (var [s,r] of replaceMap) 
      output = output.replace(new RegExp(s, 'gm'), r) 
    
  

  outputEl.textContent = output


inputEl.addEventListener('input', rep)
inputEl.dispatchEvent(new Event('input'))
textarea 
  width: 100%; 
  min-height: 100px;
<h3>Input</h3>
<textarea id="input">@Lopez de la Cerda, Antonio Gabriel Hugo David [Author]. I'm the father of @Marquez, Maria</textarea>
<h3>Output (initially empty)</h3>
<p id="output"></p>
<h3>Expected result (on initial input)</h3>
<p>@LopezdelaCerda,AntonioGabrielHugoDavid[Author]. I'm the father of @Marquez,Maria</p>

旧答案内容的备份(出于历史原因)

它至少在 Chrome 中使用这个正则表达式:

/(?<=@[a-z]+,)\s+(?![a-z]+\s+\[[a-z]+\])|(?<=(@[a-z]+,\s[a-z]+))\s+(?=\[[a-z]+\])/gmi

见:https://regex101.com/r/elTkRe/4

但您不能在 PCRE 中使用它,因为它不允许在后视中使用量词。它们必须具有固定宽度。在此处查看右侧的错误:https://regex101.com/r/ZC3XmX/2

无后顾之忧的解决方案

console.clear();

var reg = /(@[A-Za-z]+,\s[A-Za-z]+)(\s+)(\[[A-Za-z]+\])|(@[A-Z|a-z]+,)(\s+)/gm

var probes = [
  '@gotAMatch,     <<<',
  '@LongerWithMatch,        <<<',
  '@MatchHereAsWell,    <<<',
  '@Yup,         <<<<',
  '@noMatchInThisLine,<<<<<',
  '@match, match    [match]<<<<<<<',
  '@    noMatchInThisLine,    <<<<'
]

for (var i in probes) 
  console.log(probes[i].replace(reg, '$1$3$4'))
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

现场演示中[fsadsd]后面为什么会匹配空格? @HerrSerker 它也应该匹配@match, match [match]&lt;&lt;&lt;&lt;&lt;&lt;&lt;中第一个匹配之后的空格...应该变成@match,match[match]&lt;&lt;&lt;&lt;&lt;&lt;&lt; @alk 我不是这么理解的。不是所有的空格都应该被替换,而只是那些在给定模式之前或之前和之后的空格。在第二个模式中,空格在前缀中,而不是在要替换(删除)的匹配中 @Alk 您在原始问题中的描述具有误导性。你应该给出输入和预期输出的例子 @HerrSerker 在该示例中,我们有一个以@[a-z|A-Z]+ 开头的空格,因此它也应该被替换。所以如果我们有一个像Hi my name is @John, Doe [Example] and I am happy to be here 这样的句子应该变成Hi my name is @John,Doe[Example] and I am happy to be here - 这更有意义吗?另外,如果我们有类似Hi my name is @John, Smith Doe [Example] 的东西,那应该变成Hi my name is @John,SmithDoe[Example]【参考方案2】:

您需要做的是将后视转换为捕获组,以便将它们包含在替换字符串中(注意设置了不区分大小写的标志 (i)):

(@[a-z]+,)([\t ]*([a-z]+)[\t ]*(?=\[[a-z]+\])|[\t ]+)

如果要删除这些空格,请替换为 $1$3

见live demo here

【讨论】:

怎么在你的演示中,第二个例子中 foo 后面的空格没有被删除 - 它应该变成@foo,bar[john] 更新了答案。请检查。 谢谢 - 是否很难适应这种情况来处理像这样的情况 @foo, bar foo [john] -> @foo,barfoo[john] 所以基本上在 [john] 部分之前有任意数量的可能单词 你必须使用两个replace 调用然后str.replace(/@[a-z]+,([ \t]*[a-z]+)+(\s\[[a-z]+\])?/g, function($0) return $0.replace(/\s+/g, ''); )【参考方案3】:

只需更新您的 Node.js 版本。 Lookbehind 断言是 ECMAScript 2018 的一部分,并且已经在 Chromium 和 Node.js 中实现。根据http://kangax.github.io/compat-table/es2016plus/ 的说法,Chromium 70 和 Node.js 8.10 都有这个功能。

我刚刚在浏览器和 Node.js (v8.11) 中对其进行了测试,可以确认:

node -e "console.log('nothing@xyz, bla'.match(/(?<=@[A-Za-z]+,)\s+/))"

如果您无法更新,则必须使用其他策略,例如捕获和替换,这对于积极的后视来说应该不是一个大问题(消极的更难):

const hit = 'nothing@xyz, bla'.match(/(@[A-Za-z]+,)\s+/)
hit[0].replace(hit[1])

如果没有其他方法,看看这个尝试实现 Lookbehind 的项目(我还没有测试过):http://blog.stevenlevithan.com/archives/javascript-regex-lookbehind

【讨论】:

以上是关于javascript正则中使用[\s\S]*用来匹配任意字符(包括换行符)的方法不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Javascript如何判断一个变量是数字类型?

我写的javascript正则表达式为啥匹配不了我的数字?

javascript 验证IP地址的正则表达式!!!

javascript /jquery 如何split 正则表达式

python中的正则表达式匹配的问题?

用正则表达式提取wps内容