我正在尝试构建一个模式来匹配句子中的所有县 例如。 “ABCD XYZ县赫里福德郡或Co.Kent或伦敦县”
((co(unty)?\s)|(co\.\s?))?(?P<county>[a-z]{4,})(\scounty)?
但是上面的模式也将返回“ABCD”,因为“郡”周围的两个表达都是可选的。
我是否必须使用两个单独的正则表达式,还是有任何解决方法?
修改 我想做的是从句子中获取所有县。如果后面跟着“县”或者在“co。”,“co”,“county”之前,我认为这是一个县名。允许使用除以“或”之类的多个表达式。一旦匹配,下一步就是从原始字符串中删除整个表达,例如“Co.London”。
编辑2
好抱歉混淆我知道我的问题不清楚。我想做的是:
1.用户输入类似'ABCD County XYZ或Co.London或Kent County或County Herefordshire'的内容
2.我希望获得以下任何内容:“co.word”或“co word”或“county word”或“word county”理想情况下我应该得到:'ABCD County,County XYZ,Co.London,肯特郡,赫里福德郡县
3.我从匹配的表达式中删除“county”或“co”等,并根据我所拥有的县列表进行检查。如果word是一个县名,我想从原始查询中删除整个表达式。
答案 0 :(得分:1)
您可以通过首先匹配在您匹配的文本之前具有它的组,然后在它之后匹配它来执行您要查找的内容。这个解释可能不清楚,所以让我用这种方式来说明:
您希望匹配foo
之前或之后的bar
:
(bar)foo|foo(bar)
当然在这种情况下,括号不是必需的,但它是为了说明它是一个组。
在您的情况下,如果我理解正确,您需要以下内容:
((co(unty)?\s)|(co\.\s?))(?P<county>[a-z]{4,})|(?P<county>[a-z]{4,})(\scounty)
或括号减少:
(co(unty)?\s|co\.\s?)(?P<county>[a-z]{4,})|(?P<county>[a-z]{4,})\scounty
我不太确定(?P
应该是什么意思。 Regex101也不承认。
在回复Johannes' comment时,你所能做的只是匹配以大写字母开头的单词:
([Cc]o(unty|\.)? ?)([A-Z]\w+)|([A-Z]\w+) [Cc]ounty
如果单词是大写的话,那也会匹配它,因为它是句子的开头,所以你可以阻止它通过以下方式匹配:
([Cc]o(unty|\.)? ?)([A-Z]\w+)|((?<![.!?] |.\n)[A-Z]\w+) [Cc]ounty
然后,如果县名是句子的开头,它将不再匹配,但这是你必须在两者之间做出选择的东西。正则表达式不能区分句子开头的县名和常用词。
最后提到的正则表达式的Demo。
根据您的评论进行更新:您可以使用以下内容匹配其中一个命名关键字(包括不一定是县名)之后或之前的每个字词:
((?<=county\s)|(?<=co\s)|(?<=co\.))(?P<county>[a-z]{4,})|(?P<county2>[a-z]{4,})(?=\scounty)
它使用lookbehinds,因此只匹配实际的单词,而不是单词“county”,所以你甚至可以省略命名的捕获组,并直接使用匹配列表,而不是仅将其过滤到命名的捕获组。正如您在演示中所看到的,唯一匹配的实际文本是您正在寻找的文本。