继续扫描一个字符串,直到它找到 first/last 个出现的字符串

Continue scanning a string until it has found the first/last occurrence of a string

我想使用正则表达式扫描这行文本。

axhaweacb

我想获取从 "a" 到 "b" 的文本。这是我目前的模式:

pattern = "a.*?b";

当前输出是:axhaweacb(它获取了 a 和 b 之间的所有内容),但我想要返回的是 "acb"。

为什么你会问?我要申请的 logic/regex 是: 当您找到第一个 "from" 正则表达式 ("a") 时,开始扫描。如果您发现另一个出现的 "from" 字母没有找到 "last" 出现的字母 - 在本例中为 "b",请删除之前的字符串 - 即 axh 以便字符串变为:aweacb。如果您发现另一个 "from" - 在本例中为 a,但没有找到 "to" - b。删除之前的字符串,使其变为 acb。然后重新开始扫描。在这种情况下,我们找到了我们的模式 - a 到 b,没有另一个 "a" 挡在我们的路上。

我知道我可以从字符串开始子字符串化,然后删除所有内容,直到最后一次出现 "a" - 但我也想对不同的字符串重复使用它。在这种情况下,它将始终对所有内容进行子字符串化,直到最后一次出现 - 这会导致删除大量数据。

我希望我question/problem说清楚了。如果没有,请告诉我,我会尽力澄清我的问题。

谢谢。

您可以使用这个基于负前瞻的正则表达式:

a(?:(?![ab]).)*b
  • (?![ab]) 是匹配除 a 和 b`
  • 之外的任何内容的否定正则表达式
  • (?:(?![ab]).)* 匹配 0 个或多个非 a 和 b, thus giving us shortest match betweenaandb`
  • 的字符

RegEx Demo

正则表达式引擎从左到右搜索匹配项。当它发现 aa.*?b 时,它是字符串中的第一个 a。然后,找到并匹配的第一个 baxhaweacb 字符串中的最后一个字符。

惰性量词匹配与后续子模式最接近的最右侧字符,而不是可能的最短子字符串。

因此,您需要一种方法来 排除(=如果找到则失败)所有出现的前导 尾随子模式他们之间。

可以借助 tempered greedy token:

pattern = "a(?:(?!a|b).)*b";
            ^^^^^^^^^^^^^

这是一个demo