代码之家  ›  专栏  ›  技术社区  ›  Tim Büthe

为什么“*”和“+”给出不同的结果?

  •  9
  • Tim Büthe  · 技术社区  · 16 年前

    System.out.println("foo".replaceAll(".+", "bar")); // --> "bar"
    System.out.println("foo".replaceAll(".*", "bar")); //--> "barbar"
    

    我希望两者都是“bar”,因为*和+都是贪婪的,应该匹配整个字符串。(上面的例子是Java,但其他工具,如 http://www.gskinner.com/RegExr/

    7 回复  |  直到 16 年前
        1
  •  12
  •   Mehrdad Afshari    16 年前

    你说得对,两人都很贪婪,但是 ".*" 相配 字符串:第一个是 "foo" 第二个是 "" . ".+" 只会匹配

    两者都尝试匹配最长的字符串,即 “福” ".*" 能够匹配空字符串,而 ".+" 不会。

        2
  •  9
  •   Community Mohan Dere    5 年前

    http://msdn.microsoft.com/en-us/library/c878ftxe.aspx

    例如,(a?*匹配字符串“aaa”,并捕获模式(a)(a)(a)()中的子字符串。请注意,没有第五个空捕获,因为第四个空捕获会导致量词停止重复。

        3
  •  2
  •   hobbs    16 年前

    通过实验测试:replaceAll的匹配器在不前进的情况下不会在同一字符串位置匹配两次。

    实验:

    System.out.println("foo".replaceAll(".??", "[bar]"));
    

    [bar]f[bar]o[bar]o[bar]
    

    说明:

    模式 .?? replaceAll 取代 "" 具有 "[bar]" "f" 之后

    出于好奇,Perl做了一些非常类似的事情,但它应用规则的方式不同,给出了 "[bar][bar][bar][bar][bar][bar][bar]" 对于相同的输入和相同的模式-- .??

        4
  •  1
  •   Amarghosh    16 年前

    我猜是贪婪的人 .* 首先匹配整个字符串,然后开始从当前位置(字符串末尾)查找匹配项,并在退出之前匹配空字符串。

        5
  •  0
  •   SilentGhost    16 年前

    嗯,Python在这两种情况下都会产生 'bar' :

    >>> import re
    >>> re.sub('.+', 'bar', 'foo')
    'bar'
    >>> re.sub('.*', 'bar', 'foo')
    'bar'
    
        6
  •  0
  •   Stephen C    16 年前

    这是一个非常有趣的问题。

    你想想看, String.replaceAll(...) 在“*”案例中,逻辑上可以执行以下三项操作之一:

    • 尝试进行无限次的替换。

    很明显,最后一种选择是没有用的,所以我可以理解他们为什么没有这样做。但我们不知道他们为什么选择“芭芭拉”的解释而不是“酒吧”的解释。问题是没有通用的正则表达式语法标准,而只有正则表达式语义。我猜想《太阳报》的作者做了以下一件事:

    • 看看其他已经存在的实现做了什么和复制了什么,
    • 思考并做他们认为最好的事情,或者
    • 没有考虑这种边缘情况,当前的行为是无意的。

    但归根结底,他们为什么选择“芭芭拉”并不重要。事实是他们确实。。。我们只需要解决这个问题。

        7
  •  0
  •   Community Mohan Dere    5 年前

    .+ .* "foo" )。之后,剩余的空字符串输入将由

    然而,我从以下模式中发现了一个非常奇怪的结果。

    ^.*  => 'bar'
    .*$  => 'barbar'
    ^.*$ => 'bar'
    

    你能解释一下为什么它会返回上面的结果吗?起始字符串之间有什么不同( ^ )和结束字符串( $ )在正则表达式中?

    更新.1

    我尝试将输入字符串更改为以下字符串。

    请看新的结果!

    “^.*”=>

    芭芭拉

    因此,我认为,每个输入只有一个开始字符串。另一方面,当函数在输入字符串中查找匹配字符串时,它不会删除当前字符串的结束字符串。 附言:你可以很快在 http://gskinner.com/RegExr/