正则表达式在两组之间使用,其中第二组是可选的

Regex to consume between two groups where the second group is optional

我有以下字符串:

Sally: Hello there #line:34de2f
Bob: How are you today?

这些字符串由三部分组成...

我想使用正则表达式获取“名称”和可选的“行标识符”之间的“文本”。

这似乎是负面前瞻的目的:

(?<=:).*?(?!#line:.*)$

但是这个仍然捕获“行标识符”。

以下有效,但我不想实际捕获“行标识符”:

(?<=:).*?(#line:.*)?$

您可以尝试使用

(?<=:\s).*?(?=\s*#line:.*|$)

参见 this regex demo。详情:

  • (?<=:\s) - 紧接 : 和空格
  • 之前的位置
  • .*? - 除换行字符外的任何 0 个或多个字符,尽可能少
  • (?=\s*#line:.*|$) - 紧跟 0+ 个空格、#line: 字符串或字符串结尾的位置。

您也可以使用

:\s*(.*?)(?:\s*#line:.*)?$

regex demo。获取第 1 组中的内容。

详情

  • :\s* - 一个冒号,然后是 0 个或多个空格
  • (.*?) - 捕获第 1 组:除换行字符外的任何零个或多个字符,尽可能少
  • (?:\s*#line:.*)? - 一个可选的序列
    • \s* - 0+ 个空格
    • #line: - 文字 #line: 字符串
    • .* - 除换行字符外的任何零个或多个字符,尽可能多
  • $ - 字符串结尾。

另一个解决方案(适用于 Python):

\w+:\s+?(.+)?\s+?#?.*?

示例:

import re

tst1 = "Sally: Hello there #line:34de2f"
res1 = re.search(r"\w+:\s+?(.+)?\s+?#?.*?", tst1)
res1.groups(1) # ('Hello there',)

tst2 = "Bob: How are you today?"
res2 = re.search(r"\w+:\s+?(.+)?\s+?#?.*?", tst2)
res2.groups(1) # ('How are you',)
^([^:]*)[:]([^#]*)(?!line.*)

This 也可能适合您:

  • ^ - 行首
  • ([^:]*.) - 在名称
  • 的捕获组中不是冒号重复
  • [:] - 冒号(这可以简化为 :
  • [^#] - 不是散列符号(在捕获组内并重复)([^#]*)
  • (?!line.*) - 否定前瞻。