匹配两到三个单词的正则表达式,但如果第三个单词是特定的单词,则不匹配第三个单词。

3
我需要匹配特定的模式,但是我无法用正则表达式做到。我想要匹配人名,它们总是遵循相同的模式。以下是一些组合:
1. Mr. Snow 2. Mr. John Snow 3. Mr. John Snow (Winterfall of the nord lands)
我的问题出现在有时候我会有类似以下的情况:Mr. Snow and Ms. Stark,它也会捕获and。所以我正在寻找一个正则表达式,只有当第二个名称不是and时才捕获它。这里我正在寻找["Mr. Snow", "Ms. Stark"]
我最好的尝试如下: (M[rs].\s\w+(?:\s[\w-]+)(?:\s\([^\)]*\))?) 请注意,第二个名称在非捕获组中。因为我想使用负向先行断言,但如果我那样做,第一个单词就无法被捕获(因为整个名称不匹配),而我需要捕获它。
有什么想法吗?
这里是一些文本以供快速检查: 链接
4个回答

4

因为这是一个人的名字,所以您还可以检查单词的首字母是否为大写字母。

M[rs].\s[A-Z]\w+(?:\s[A-Z]\w+(?:\s\([^\)]*\))?)?

查看正则表达式演示


4

以下是我的意见:

\bM[rs]\.\h(\p{Lu}\p{Ll}+(?:[\h-]\p{Lu}\p{Ll}+)*)\b

查看在线演示


  • \b - 匹配词边界;
  • M[rs]\.\h - 匹配水平空格后跟着Mr.Ms.
  • (\p{Lu}\p{Ll}+(?:[\h-]\p{Lu}\p{Ll}+)*) - 一个捕获组和一个嵌套的非捕获组,用于匹配一个大写字母后面跟着小写字母,并通过空格或连字符连接0个或多个2级名称;
  • \b - 匹配词边界。

3
如果第二个名称存在且不是and,则此正则表达式会捕获第一组中的名字1和第二组中的名字2。
(?<=M[rs]\. )(\w+)(?: (?!and)(\w+))?

查看实时演示


如果您想将标题捕获为第1组,将名称捕获为第2和第3组,请将逆向预查更改为捕获组:

(M[rs]\.) (\w+)(?: (?!and)(\w+))?

3

匹配姓名是很困难的,可以查看这篇文章了解详细信息:

程序员关于姓名的谬论

对于您提供的示例,您可以使用以下方法:

\bM[rs]\.(?: (?!M[rs]\.|and )\w+)*

解释

  • \b 单词边界
  • M[rs]\. 匹配Mr或Ms后跟一个句点(注意需要转义)
  • (?: 非捕获组
    • 匹配一个空格(如果想要允许换行,可以使用\s+)
    • (?!M[rs]\.|and ) 负向先行断言,断言当前位置右侧没有直接跟着Mr或Ms或and的内容
    • \w+ 匹配1个或多个单词字符
  • )* 关闭非捕获组并可选重复

正则表达式演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接