【问题标题】:Regex to find all possible occurrences of text starting and ending with ~正则表达式查找所有可能出现的以 ~ 开头和结尾的文本
【发布时间】:2016-03-31 10:44:11
【问题描述】:

我想找出所有可能出现在两个~s 之间的文本。

例如:对于文本~*_abc~xyz~ ~123~,我想要以下表达式作为匹配模式:

  1. ~*_abc~
  2. ~xyz~
  3. ~123~

注意它可以是字母或数字。

我尝试使用正则表达式~[\w]+?~,但它没有给我~xyz~。我希望重新考虑~。但我不希望只是 ~~ 作为可能的匹配项。

【问题讨论】:

  • (?=(~.*?~)) #overlapping_matches #lookahead
  • 我使用了 rubular[.]com 来验证 .似乎第一个 ~*abc~ 没有被您的正则表达式拾取。
  • @AbhishekAsh 您的要求和示例字符串/输出不同步
  • @WiktorStribiżew:你能解释一下吗?怎么不同步。我会继续纠正它。
  • "它可以是字母或数字" 但*_ 既不是字母也不是数字...

标签: java regex


【解决方案1】:

capturing inside a positive lookahead 与以下正则表达式一起使用:

有时,您需要在同一个单词中匹配多个匹配项。例如,假设您想从ABCD 之类的字符串中提取ABCDBCDCDD。你可以用这个单一的正则表达式来做到这一点:

(?=(\w+))

在字符串的第一个位置(A 之前),引擎开始第一次匹配尝试。前瞻断言紧跟当前位置的是一个或多个单词字符,并将这些字符捕获到第 1 组。前瞻成功,匹配尝试也成功。由于该模式不匹配任何实际字符(前瞻仅查找),因此引擎返回零宽度匹配(空字符串)。它还返回第 1 组捕获的内容:ABCD

然后引擎移动到字符串中的下一个位置并开始下一次匹配尝试。再次,前瞻断言紧跟该位置的是单词字符,并将这些字符捕获到第 1 组。匹配成功,第 1 组包含BCD

引擎移动到字符串中的下一个位置,该过程会重复CD,然后是D

所以,使用

(?=(~[^\s~]+~))

regex demo

(?=(~[^\s~]+~)) 模式检查字符串中的每个位置并搜索~,后跟除空格和~ 以外的1+ 个字符,然后再搜索另一个~。由于索引仅在检查位置后移动,而不是在值被捕获时移动,因此会提取重叠的子字符串。

Java demo:

String text = " ~*_abc~xyz~ ~123~";
Pattern p = Pattern.compile("(?=(~[^\\s~]+~))");
Matcher m = p.matcher(text);
List<String> res = new ArrayList<>();
while(m.find()) {
    res.add(m.group(1));
}
System.out.println(res); // => [~*_abc~, ~xyz~, ~123~]

以防万一有人需要Python demo

import re
p = re.compile(r'(?=(~[^\s~]+~))')
test_str = " ~*_abc~xyz~ ~123~"
print(p.findall(test_str))
# => ['~*_abc~', '~xyz~', '~123~']

【讨论】:

  • 你的回答总是让我吃惊
  • @WiktorStribiżew:感谢您的回答。在这件事上敲了我的头很长一段时间。符合我的要求。
【解决方案2】:

试试这个[^~\s]*

此模式不考虑字符~ 和空格(称为\s)。

我已经测试过了,它适用于你的字符串,这里是the demo

【讨论】:

    猜你喜欢
    • 2021-09-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多