正则表达式:谁更贪婪? - java

我主要关心的是Java风格,但是我也希望了解其他信息。

假设您有一个像这样的子模式:

(.*)(.*)

虽然这不是很有用,但可以说这两个捕获组(例如\1\2)是更大模式的一部分,该模式与对这些组的反向引用匹配,等等。

因此,两者都是贪婪的,因为他们试图捕获尽可能多的东西,只在需要时才花更少的时间。

我的问题是:谁更贪婪? \1是否具有优先权,仅在必须时才赋予\2份额?

关于什么:

(.*)(.*)(.*)

假设\1确实具有优先级。假设它过于贪婪,然后吐出一个字符。谁先得到它?总是\2还是\3

假设是\2获得\1的拒绝。如果仍然无法解决问题,现在谁吐出来? \2吐到\3还是\1首先吐出另一个到\2

奖金问题

如果您这样写,会发生什么:

(.*)(.*?)(.*)

现在\2不愿意。这是否意味着\1吐出到\3,而\2仅不情愿地接受\3的拒绝?

也许我不给出具体的例子来展示我如何使用这些模式,这对我来说是一个错误,但是这里有一些:

System.out.println(
    "OhMyGod=MyMyMyOhGodOhGodOhGod"
    .replaceAll("^(.*)(.*)(.*)=(\\1|\\2|\\3)+$", "<$1><$2><$3>")
); // prints "<Oh><My><God>"

// same pattern, different input string
System.out.println(
    "OhMyGod=OhMyGodOhOhOh"
    .replaceAll("^(.*)(.*)(.*)=(\\1|\\2|\\3)+$", "<$1><$2><$3>")
); // prints "<Oh><MyGod><>"

// now \2 is reluctant
System.out.println(
    "OhMyGod=OhMyGodOhOhOh"
    .replaceAll("^(.*)(.*?)(.*)=(\\1|\\2|\\3)+$", "<$1><$2><$3>")
); // prints "<Oh><><MyGod>"

参考方案

添加您的具体示例将大大改变问题的性质。正如我在第一个答案中所述,它仍然开始,第一个(.*)吞噬了所有字符,第二和第三组让它们拥有它们,但是随后必须匹配一个等号。

显然,字符串的末尾没有一个,因此#1组逐个返回字符,直到正则表达式中的=可以与目标中的=匹配为止。然后,正则表达式引擎开始尝试匹配(\1|\2|\3)+$,真正的乐趣开始了。

第1组放弃了d,而第2组(仍然为空)接受了o,但是其余正则表达式仍然无法匹配。第1组放弃了od,而第2组匹配了Oh,但是其余正则表达式仍然无法匹配。因此,随着第三个小组的参与,他们三个人以各种可能的方式切分了输入内容,直到实现整体匹配为止。 RegexBuddy报告说,到达那里需要13,426个步骤。

在第一个例子中,贪婪(或缺乏贪婪)并不是一个真正的因素。匹配的唯一方法是将单词MyGodOh捕获在不同的组中,因此最终会发生这种情况。哪一个小组捕​​获哪个词都没有关系-正如我之前所说的,先来先服务。

在第二个和第三个示例中,仅需将前缀分为两个块:MyGodMyGod。组2在第二个示例中捕获MyGod,因为它排在第二行并且很贪心,就像在第一个示例中一样。在第三个示例中,每当第1组丢弃一个字符时,第2组(不愿意)就让第3组代替它,因此这就是最后一个拥有ojit_code的字符。

当然,它比这更复杂(且乏味),但是我希望这能回答您的问题。我不得不说,这是您选择的一个有趣的目标字符串。如果正则表达式引擎有可能出现性高潮,我认为这些正则表达式将使它高潮。 😀

正则表达式-集团价值替代 - java

我不确定是否可以这样做,但是一旦完成匹配,我需要一种方法来用在运行时动态声明的字符串替换我的regex表达式中指定的编号组的值。举一个简单的例子,类似...(/)?([A-Za-z0-9])?(/)?$ 我希望能够为第2组插入替换项。我目前正在使用Java的Matcher类。 参考方案 是的,那是可行的。查看我对this question的回答,以了解如何。…

与哪些运算符>>兼容 - java

我这里没有什么代码int b=3; b=b >> 1; System.out.println(b); 它可以完美工作,但是当我将变量b更改为byte,short,float,double时,它包含错误,但是对于变量int和long来说,它可以完美工作,为什么它不能与其他变量一起工作? 参考方案 位移位运算符(例如>>)与任何整数类型兼…

Java-搜索字符串数组中的字符串 - java

在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…

Java Applet的URLConnection与PHP无效 - java

我已经研究了Oracle文档和示例,但仍然无法正常工作。我有一个Java Applet,它只是尝试使用URLConnection和OutputStreamWriter通过POST将文本字段发送到PHP脚本。 Java方面似乎工作正常,没有引发异常,但是PHP在我的页面上未显示任何输出。我是PHP新手,因此请耐心等待。这是相关的Java部分: try { UR…

Java Globbing模式以匹配目录和文件 - java

我正在使用递归函数遍历根目录下的文件。我只想提取*.txt文件,但不想排除目录。现在,我的代码如下所示:val stream = Files.newDirectoryStream(head, "*.txt") 但是这样做将不会匹配任何目录,并且返回的iterator()是False。我使用的是Mac,所以我不想包含的噪音文件是.DS_ST…