正则表达式捕获可选令牌后的所有内容
Regex to capture everything after optional token
我的字段包含以下可能格式的数据(每行都有不同的可能性):
AAA - Something Here
AAA - Something Here - D
Something Here
请注意,第一组字母 (AAA) 可以有不同的长度。
我试图捕获的是使用 PCRE 的“Something Here”或“Something Here - D”(如果存在),但我无法让正则表达式在所有三种情况下都正常工作。我试过:
- (.*)
适用于情况 1 和 2,但显然不适用于情况 3;
(?<= - )(.*)
也适用于情况 1 和 2;
(?! - )(.+)| - (.+)
适用于情况 2 和 3 但不适用于情况 1。
我觉得我快要崩溃了,但我似乎无法破解它。
在此先感谢您的帮助。
编辑:我意识到我的要求不清楚。如果后面有一个“-D”(数据中的字母是任意的,但应该只是一个字符),也需要捕获它。
您可以使用
^(?:.*? - )?\K.*?(?= - | *$)
^(?:.*?\h-\h)?\K.*?(?=\h-\h|\h*$)
详情
^
- 字符串的开头
-(?:.*? - )?
- 一个可选的非捕获组匹配除换行符之外的任何 0+ 个字符,尽可能少到第一个 space-space
\K
- 匹配重置运算符
.*?
- 除换行字符外的任何 0+ 个字符尽可能少
(?= - | *$)
- space-space
或直到字符串末尾的 0+ 个空格应紧跟在右侧。
请注意 \h
匹配任何水平空白字符。
关于您尝试过的模式:
- (.*)
此模式将匹配第一次出现的 -
,然后匹配该行的其余部分。对于第二个示例,它会匹配太多,因为 .*
也会匹配第二次出现的 -
(?<= - )(.*)
这个模式将匹配第一个没有 -
的例子,因为它断言应该直接出现在左边
(?! - )(.+)| - (.+)
此模式使用否定前瞻,它断言直接在右边的不是 (?! - )
。由于示例的none以 -
开头,由于.+
的否定先行后会直接匹配整行,而交替后的第二部分|
将不会匹配评价
如果第一组字母的长度可以变化,您可以匹配特定匹配的 1 个或多个大写字符 [A-Z]+
或 1+ 个单词字符 \w+
.
要获得更广泛的匹配,您可以使用 \S+
匹配 1 个或多个非空白字符
^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*
说明
^
字符串开头
(?:\S+\h-\h)?
可选择匹配第一组非空白字符,后跟 -
水平空白字符
\K
清除匹配缓冲区(忘记当前匹配的是什么)
\S+
匹配1+个非空白字符
(?:
非捕获组
\h(?!-\h)
匹配水平空白字符并断言直接在右边的不是 -
后跟另一个水平空白字符
\S+
匹配 1+ 个非空白字符
)*
关闭非捕获组并重复1+次以匹配更多由空格分隔的“单词”
编辑
要匹配可选的连字符和尾随的单个字符,您可以添加可选的非捕获组 (?:-\h\S\h*)?$
并在模式应匹配整个字符串时断言字符串的结尾:
^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*\h*(?:-\h\S\h*)?$
^(?:[A-Z]+ - \K)?.*\S
因为 "Something Here" 可以是任何东西,所以没有理由专门描述模式中最终的最后一个字母。你不需要更复杂的东西。
对于这种模式,我假设您对尾随空格不感兴趣,这就是我以 \S
结尾的原因。如果要保留它们,请删除 \S
并将之前的量词更改为 +
.
我的字段包含以下可能格式的数据(每行都有不同的可能性):
AAA - Something Here
AAA - Something Here - D
Something Here
请注意,第一组字母 (AAA) 可以有不同的长度。
我试图捕获的是使用 PCRE 的“Something Here”或“Something Here - D”(如果存在),但我无法让正则表达式在所有三种情况下都正常工作。我试过:
- (.*)
适用于情况 1 和 2,但显然不适用于情况 3;
(?<= - )(.*)
也适用于情况 1 和 2;
(?! - )(.+)| - (.+)
适用于情况 2 和 3 但不适用于情况 1。
我觉得我快要崩溃了,但我似乎无法破解它。
在此先感谢您的帮助。
编辑:我意识到我的要求不清楚。如果后面有一个“-D”(数据中的字母是任意的,但应该只是一个字符),也需要捕获它。
您可以使用
^(?:.*? - )?\K.*?(?= - | *$)
^(?:.*?\h-\h)?\K.*?(?=\h-\h|\h*$)
详情
^
- 字符串的开头 -(?:.*? - )?
- 一个可选的非捕获组匹配除换行符之外的任何 0+ 个字符,尽可能少到第一个space-space
\K
- 匹配重置运算符.*?
- 除换行字符外的任何 0+ 个字符尽可能少(?= - | *$)
-space-space
或直到字符串末尾的 0+ 个空格应紧跟在右侧。
请注意 \h
匹配任何水平空白字符。
关于您尝试过的模式:
- (.*)
此模式将匹配第一次出现的-
,然后匹配该行的其余部分。对于第二个示例,它会匹配太多,因为.*
也会匹配第二次出现的-
(?<= - )(.*)
这个模式将匹配第一个没有-
的例子,因为它断言应该直接出现在左边(?! - )(.+)| - (.+)
此模式使用否定前瞻,它断言直接在右边的不是(?! - )
。由于示例的none以-
开头,由于.+
的否定先行后会直接匹配整行,而交替后的第二部分|
将不会匹配评价
如果第一组字母的长度可以变化,您可以匹配特定匹配的 1 个或多个大写字符 [A-Z]+
或 1+ 个单词字符 \w+
.
要获得更广泛的匹配,您可以使用 \S+
^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*
说明
^
字符串开头(?:\S+\h-\h)?
可选择匹配第一组非空白字符,后跟-
水平空白字符\K
清除匹配缓冲区(忘记当前匹配的是什么)\S+
匹配1+个非空白字符(?:
非捕获组\h(?!-\h)
匹配水平空白字符并断言直接在右边的不是-
后跟另一个水平空白字符\S+
匹配 1+ 个非空白字符
)*
关闭非捕获组并重复1+次以匹配更多由空格分隔的“单词”
编辑
要匹配可选的连字符和尾随的单个字符,您可以添加可选的非捕获组 (?:-\h\S\h*)?$
并在模式应匹配整个字符串时断言字符串的结尾:
^(?:\S+\h-\h)?\K\S+(?:\h(?!-\h)\S+)*\h*(?:-\h\S\h*)?$
^(?:[A-Z]+ - \K)?.*\S
因为 "Something Here" 可以是任何东西,所以没有理由专门描述模式中最终的最后一个字母。你不需要更复杂的东西。
对于这种模式,我假设您对尾随空格不感兴趣,这就是我以 \S
结尾的原因。如果要保留它们,请删除 \S
并将之前的量词更改为 +
.