"^(?:(2\d\d\d)\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+(\S+)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$"
目前,这可以解析像
这样的字符串2009 IA H.B. 184 (NS)
如何解析像
这样的文本2009 IA HEART RATE 184 (NS)
我正在寻找一个可以解析间隔词HEART RATE的调整。
编辑: 只要第三个单词没有间隔开来,它似乎就可以工作。喜欢例如 它适用于2009 IA REG 184(NS)......但是,只要第三个单词实际上由空格组成,它就会像HEART RATE一样失控。
答案 0 :(得分:0)
我将假设您想要所有那些空格分隔的单词,这些单词现在不起作用,因为您正在尝试阅读“第三个单词”(第二个正则表达式捕获组)HEART RATE
通过阅读直到找到一个空格(第二个(\S+)
)。
要解决此问题,我会假设您“第三个单词”是所有空格分隔的单词,直到您点击以No.
开头的数字或单词(告诉我这是否是假设是错误的!)。这是解决方案中的((?:\S|\s(?!\d|No\.))+)
。
这是我的解决方案:
"^(?:2\d{3}\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+((?:\S|\s(?!\d|No\.))+)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$"
当我在
上测试时2009 IA H.B. 184(NS)
它(仍然)发现第三个单词是H.B.
当我在
上测试时2009年IA心率184(NS)
它找到第三个单词HEART RATE
当我在
上测试时2009 IA心率无184(NS)
它找到第三个单词HEART RATE None
当我在
上测试时2009年IA心率184(NS)
它找到第三个单词HEART RATE
看起来不错?
PS gskinner太棒了。
答案 1 :(得分:0)
让我们将表达分解为其部分:
^
从一行的开头开始。
(?:(2\d\d\d)\s+)?
如果出现一年,则在组1中捕获它(组0是整个事物)。如果没有给出年份,则无关紧要。
(?:Comm\. Rep\.\s+)?
接受字符串“Comm.Rep。”和一个或多个空格字符但不捕获它。如果不存在则无所谓。
(?:CONG\s+)?
接受字符串“CONG”和一个或多个空格字符,但不捕获它。如果不存在则无所谓。
(\S+)\s+(\S+)\s+
必须存在两个至少一个字符长度的非空白字符块,每个字符长度后面跟着至少一个空格。捕获第2组和第3组中的块。
(?:No\.\s+)?
接受字符串“否”和一个或多个空格字符但不捕获它。如果不存在则无所谓。
(\S+)
必须存在至少一个非空白字符的另一个块。在第4组中捕获它。
(?:\s+\(.*?\))?
接受至少一个空格后跟任何内容,只要它在括号内但不捕获它。如果不存在则无所谓。
$
然后该行必须结束。
以下是零件如何映射到当前匹配(省略开始和结束行):
2009 IA H.B. 184 (NS)
---- ------- --- ----
2 5 7 8
你的问题在于表达式的第5部分,因为只接受了两个“块”:
2009 IA HEART RATE 184 (NS)
---- ------------- --- ----
2 ??? 7 8
假设字符串“HEART RATE”也应该进入第三组,你需要用这个替换第五部分:
(\S+)\s+
接受至少一个非空白字符的块,后跟至少一个空格,并在第2组中捕获它(未更改)。
和
(.+?)\s+
接受至少一个后跟空格的字符并捕获除组3中最后一个空格以外的所有字符。
所以,这是你需要的表达作为一个整体:
^(?:(2\d\d\d)\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+(.+?)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$
顺便说一下,我对http://regexpal.com感到非常满意。
PS:Carl Walsh的解决方案在性能方面更加智能,因为它不依赖于非贪婪(或懒惰)捕获。