Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS string replace仅每隔一次替换一次_Javascript_Regex - Fatal编程技术网

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”
  • 结果将是“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 run
    console.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(" ")
    >>> ""