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]这个组合就可以匹配所有字符了。
但是换行符是匹配不到的:
//-- 通过正则表达式来替换换行符
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]*?)也不行。
Javascript 替代品中的正则表达式 Lookbehind
【中文标题】Javascript 替代品中的正则表达式 Lookbehind【英文标题】:Regex Lookbehind in Javascript Alternatives 【发布时间】:2019-01-18 11:41:09 【问题描述】:我正在尝试在 JS 中使用以下正则表达式:
(?<=@[A-Z|a-z]+,)\s|(?<=@[A-Z|a-z]+,\s[A-Z|a-z]+)\s(?=\[[A-Z|a-z]+\])
翻译成:
匹配所有以 : 开头的空格
@
后跟A-Z
或a-z
范围内的任意数量的字符
后跟逗号
或
匹配前面的所有空格:
@
后跟A-Z
或a-z
范围内的任意数量的字符
A-Z
或a-z
范围内的任意数量的字符
AND 成功:
[
后跟A-Z
或a-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]<<<<<<<
中第一个匹配之后的空格...应该变成@match,match[match]<<<<<<<
@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]*用来匹配任意字符(包括换行符)的方法不起作用的主要内容,如果未能解决你的问题,请参考以下文章