匹配,如果某事在某个词之前或之后

时间:2014-02-08 20:41:59

标签: php regex

我正在尝试构建一个模式来匹配句子中的所有县 例如。 “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是一个县名,我想从原始查询中删除整个表达式。

1 个答案:

答案 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)

demo

它使用lookbehinds,因此只匹配实际的单词,而不是单词“county”,所以你甚至可以省略命名的捕获组,并直接使用匹配列表,而不是仅将其过滤到命名的捕获组。正如您在演示中所看到的,唯一匹配的实际文本是您正在寻找的文本。