Javascript JS string replace仅每隔一次替换一次
我有以下几点:Javascript JS string replace仅每隔一次替换一次,javascript,regex,Javascript,Regex,我有以下几点: "a a a a".replace(/(^|\s)a(\s|$)/g, '$1') 我希望结果是',但我得到的是'a'。谁能解释一下我做错了什么 澄清:我想做的是删除所有出现的由空格(即整个标记)包围的'a'。使用以下方法: "a a a a".replace(/(^|\s*)a(\s|$)/g, '$1') 用“*替换所有出现的“a” 问候语第一个“a”匹配。 然后它将尝试与“a”匹配,后者将首先跳过a,然后匹配“a”。 然后它将尝试与“a”匹配,而“a”不匹配 第一个匹配
"a a a a".replace(/(^|\s)a(\s|$)/g, '$1')
我希望结果是'
,但我得到的是'a'
。谁能解释一下我做错了什么
澄清:我想做的是删除所有出现的由空格(即整个标记)包围的'a'
。使用以下方法:
"a a a a".replace(/(^|\s*)a(\s|$)/g, '$1')
用“*替换所有出现的“a”
问候语第一个“a”匹配。
然后它将尝试与“a”匹配,后者将首先跳过a,然后匹配“a”。
然后它将尝试与“a”匹配,而“a”不匹配
"a a a a".replace(/(?:\s+a(?=\s))+\s+|^a\s+(?=[^a]|$|a\S)|^a|\s*a$/g, '')
这是因为这个正则表达式
/(^|\s)a(\s |$)/g
将前一个字符和下一个字符与每个a匹配
在字符串“a”
中,正则表达式匹配:
- “a”,则要检查的字符串变为“a”$(但现在字符串的开头不是开头,前面没有空格)
- “a”(第三个a),然后变成“a”$(因为前面没有空格,所以不匹配)
正如其他人试图指出的那样,问题在于正则表达式作为比赛的一部分会消耗周围的空间。下面是一个[希望]更直接的解释,解释为什么正则表达式不能像你预期的那样工作: 首先让我们分解正则表达式,它表示匹配空格或字符串的开头,后跟“a”,后跟空格或字符串的结尾 现在,让我们将其应用于字符串。我在字符串下面添加了字符索引,以便更轻松地讨论:
a a a a
0123456
正则表达式查看0索引字符,并在该位置找到一个“a”,然后在索引2处找到一个空格。这是一个匹配项,因为它是字符串的开头,后面跟着一个a,后面跟着一个空格。匹配项的长度是2(“a”和空格),因此我们使用两个字符,然后在索引2处开始下一次搜索
字符2('a')既不是空格,也不是字符串的开头,因此它与正则表达式的开头不匹配,因此我们使用该字符(不替换它)并继续下一个字符
字符3是一个空格,后面跟一个“a”,后面跟另一个空格,这是我们正则表达式的匹配项。我们将其替换为一个空字符串,使用匹配项的长度(3个字符-“a”),然后转到索引6
字符6('a')既不是空格,也不是字符串的开头,因此它与正则表达式的开头不匹配,因此我们使用该字符(不替换它)并继续下一个字符
现在我们已经到了终点,所以我们结束了
regex@caeth建议(/(^ |\s+)a(?=\s |$)/g
)起作用的原因是因为?=
量词。来自:
仅当x后跟y时匹配x。例如,/Jack(?=Sprat)/
仅当“Jack”后跟“Sprat”时匹配“Jack”。/Jack(?=Sprat|Frost)/
仅当“Jack”后跟“Sprat”或“Frost”时匹配“Jack”。但是,“Sprat”和“Frost”都不是匹配结果的一部分
因此,在本例中,?=
量词检查以下字符是否为空格,而不实际使用该字符
(^|\s)a(?=\s|$)
尝试此操作。替换为$1
。请参阅演示
或者,您可以将字符串拆分、过滤并粘回:
"a ba sl lf a df a a df r a".split(/\s+/).filter(function (x) { return x != "a" }).join(" ")
>>> "ba sl lf df df r"
"a a a a".split(/\s+/).filter(function (x) { return x != "a" }).join(" ")
>>> ""
或者在ECMAScript 6中:
"a ba sl lf a df a a df r a".split(/\s+/).filter(x => x != "a").join(" ")
>>> "ba sl lf df df r"
"a a a a".split(/\s+/).filter(x => x != "a").join(" ")
>>> ""
我假设没有前导空格和尾随空格。如果要删除该假设,可以将筛选器更改为
x&&x!='a'
。为什么会跳过第二个“a”?另外,您的解决方案不正确,因为它将'ba a'
更改为'b'
@baruch runconsole.log('''+'ba')。替换(/(^\s+)a=\s$)/g、 “)+”;
您将看到它确实输出了“ba”
。这并不会删除“a”周围的所有空格,请尝试使用“a”周围的其他文本,例如:console.log(“+”a fdsds a“。替换(/(^\s+)a(?=\s$)/g,)+”);@baruch我现在已经更新了我的正则表达式,请再次检查。将跳过第二个a,因为它与您的正则表达式不匹配,第二次它与“a$(不带字符串开头)@hwnd No匹配,因为这也将与“a-a”匹配。替换(/(?:^\s)a(?=\s$)/g,)?接受最佳解释。我最后使用的正则表达式是/(?:^ |\s)a(?=\s |$)/g
,替换为'
"a ba sl lf a df a a df r a".split(/\s+/).filter(x => x != "a").join(" ")
>>> "ba sl lf df df r"
"a a a a".split(/\s+/).filter(x => x != "a").join(" ")
>>> ""