我正在尝试从混乱的字符串中提取名称,如下所示:
genus species subsp. name […] x name […] var. name; genus2 species2 subsp. name2 var. name2
genus species subsp. name […] x name […] var. name
genus species subsp. name […] var name
genus species subsp. name var. name
genus species subsp. name
[…]
可以是没有规则模式的任何字符的连续。
所需的输出是:
subsp. name x name var. name
subsp. name x name var. name
subsp. name var. name
subsp. name var. name
subsp. name
我的正则表达式如下:
(?i).*?\b((?:aff|cf|ssp|subsp|var)[\.\s]+)([a-z-]+).*?(\sx\s+[a-z-]+)?.*?(\svar[\.\s]+[a-z-]+)?.*
这里是demo。
我正在使用惰性量词*?
在我所找到的字符串中查找某种锚点(例如subsp
,x
和var
)的首次出现可以用来匹配给定的模式。
问题在于我无法在所有实例上都使用正则表达式,因为(\sx\s+[a-z-]+)?
和(\svar[\.\s]+[a-z-]+)?
是可选的,因为匹配的模式并不在所有字符串中都存在。
是否有解决此问题的简单解决方案?
答案 0 :(得分:0)
您可以将可选模式与可选的非捕获组包装在一起,以使必要的捕获组必须,并强制正则表达式引擎至少进行一次搜索模式的尝试。
这意味着您需要将所有.*?(pattern-to-extract)?
模式更改为(?:.*?(pattern-to-extract))?
。当整个组是可选的时,它可以匹配一个空字符串并认为作业已完成。当该组被一个可选的组包装时,它至少要尝试一次,并且保证初始的.*?
会被扩展到捕获组模式所需的次数。
使用
(?i).*?\b((?:aff|cf|ssp|subsp|var)[.\s]+)([a-z-]+)(?:.*?(\sx\s+[a-z-]+))?(?:.*?(\svar[.\s]+[a-z-]+))?.*
请注意,字符类中的点与文字点匹配,无需转义。
请参见regex demo。