Regex 匹配两个条件中的第一个
我的问题很简单,但我一直在努力解决它。我有两种类型的字符串:一种有分号,另一种没有。两者都有冒号Regex 匹配两个条件中的第一个,regex,Regex,我的问题很简单,但我一直在努力解决它。我有两种类型的字符串:一种有分号,另一种没有。两者都有冒号 Reason: A chosen reason Delete: Other: testing Reason for action: Other; testing Blah: Other; testing;testing 如果字符串有分号,我想匹配第一个分号之后的任何内容。如果没有分号,我希望匹配第一个冒号之后的所有内容。对于上面的行,我应该得到: A chosen reason Other: te
Reason: A chosen reason
Delete: Other: testing
Reason for action: Other; testing
Blah: Other; testing;testing
如果字符串有分号,我想匹配第一个分号之后的任何内容。如果没有分号,我希望匹配第一个冒号之后的所有内容。对于上面的行,我应该得到:
A chosen reason
Other: testing
testing
testing;testing
我可以使用获得要匹配的分号;(.*)
我可以使用:(.*)
来匹配冒号
我试着使用这样的替代方法:;(.*):(.*)
认为如果顺序正确,我可以让它先匹配分号,如果没有分号,再匹配冒号,但它总是匹配冒号
我做错了什么
编辑
我在上面添加了另一个测试用例,以符合我所述的要求。对于没有分号的字符串,它应该匹配第一个冒号
而且,“原因”可以是任何东西,所以我在测试用例中也要澄清这一点
第二次编辑
为了澄清,我正在使用POSIX正则表达式(在PostgeSQL中使用)。我猜您可能想要设计一个表达式,可能类似于:
:\s*(?:[^;\r\n]*;)?\s*(.*)$
这里有一个快速正则表达式(233步),没有任何外观
.*?:\s*(?:([^\n;]+)|.*?;\s*(.*))$
查看正则表达式
更新:匹配任何占位符。除了原因之外,还有一个选项是首先使用检查字符串是否没有代码>如果没有,则匹配到第一个:
,并在组1中捕获其余的
如果存在代码>匹配到第一个分号,并在组1中捕获其余分号
对于问题中所述的逻辑:
- 如果字符串有分号,我想匹配第一个分号之后的任何内容
- 如果没有分号,我希望匹配第一个冒号之后的所有内容
您可以使用:
^(?:(?!.*;)[^\r\n:]*:|[^;\r\n]*;)[ \t]*(.*)$
解释
^
字符串的开头
(?:
非捕获组
(?!.*)
(受Postgresql支持),断言字符串不包含;
[^\r\n::*:
如果是这种情况,请匹配0+次非:
或换行符,然后匹配:
|
或
[^;\r\n]*;
匹配0+次非;
或换行符,然后匹配;
)
关闭非捕获组
[\t]*
匹配0+个空格或制表符
(.*)
捕获组1,匹配任意字符0+次
$
字符串结尾
|应如何处理原因:其他;测试:什么代码>或<代码>原因:其他;测试;什么代码>?@MonkeyZeus第一个分号后的任何内容都应返回。@MonkeyZeus添加了编辑以澄清您的问题。什么是正则表达式引擎?请参阅^(?:[^;:]*:(?!.*)\s*(.*)|.*?;\s*(.*)
,@WiktorStribiżew我正在使用POSIX引擎。我需要这个在PostgreSQL中工作。我已经更新了我的问题。你测试过了吗?如果有两个分号并且没有分号,那么这个问题在第一个冒号之后不匹配。请参阅我编辑的答案中的第二个示例。在冒号之前添加了非贪婪检查,=>.*:(?(?!!*)(.*)(.*)|.*;(*))这在演示中有效,但在POSIX引擎中无效。请不要仅将代码作为答案发布,而要包括对代码的作用以及它如何解决问题的解释。带有解释的答案通常质量更高,更有可能吸引更多的选票。这非常有效,只是我想避开硬编码的“原因”。那只是一个占位符名称。我更新了我的问题来澄清。我更喜欢这个解决方案。如果您用*?
替换原因,则此功能有效。如果您按照@palvarez的建议将原因
替换为*?
,则此方法有效。不仅可以在演示中使用,还可以在POSIX引擎中使用。@gnarlybracket什么应该是测试的匹配项;测试:测试;test
我希望正则表达式不会硬编码“Reason”,因为那只是一个占位符。我更新了我的问题来澄清。这在演示中有效,但在POSIX引擎中不起作用。
^(?:(?!.*;)[^\r\n:]*:|[^;\r\n]*;)[ \t]*(.*)$