Php 从正则表达式获取所有名称

Php 从正则表达式获取所有名称,php,regex,Php,Regex,我为字符串中的各种名称制作了一个正则表达式: $nameRegex = "/[A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ']" . "[.A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽa-z-àáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšž']" . '+\b(?: \b' . "[A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍ

我为字符串中的各种名称制作了一个正则表达式:

$nameRegex = "/[A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ']" .
    "[.A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽa-z-àáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšž']" .
    '+\b(?: \b' .
    "[A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ']?[van|de]" .
    "[A-Z-ÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽa-z-àáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšž']+\b)*/u";
我正在尝试匹配所有非标准案例,例如:

John Doe waves                        | John Doe
Bakary N'Diaye says hello             | Bakary N'Diaye
Iván Aguilar goes well                | Iván Aguilar
Cisteró shot                          | Cisteró
Dan I Soylu shots                     | Dan I Soylu
Mike van der Hoorn with a cross       | Mike van der Hoorn
M.J. Williams takes a shot            | M.J. Williams
Donny van de Beek left foot           | Donny van de Beek
Mike van der Hoorn hello              | Mike van der Hoorn
Artak G. Grigoryan with through ball  | Artak G. Grigoryan
Trent Alexander-Arnold after a break  | Trent Alexander-Arnold
然而,我的一个在匹配这些名字方面做得很差——在这里,你可以看到它在起作用


我如何改进我的正则表达式,使它能够捕获所有的名称?(名字在句子的开头)

也许,一个类似于

^([\p{L} '.-]+?)(?:\s[a-z]+)*\h*$
可以研究(使用
preg\u match\u all
)其中有两个组。左边的起始组是名称的捕获组,右边的第二个是非捕获组,用于收集之后的所有内容,我们对这些内容不感兴趣

测试1 产出1
在左侧的输入字符串中,似乎没有问题,因为每一行都以一个名称开头。但在右边,一行中有小写单词,中间有空格。在这里,我们试着写一份声明来找出这些,甚至可能是积极的前瞻:

(?=(?:\s[a-z]+)*\h*$)
然后是第二句话

^[\p{L} '.-]+?
我们收集这些名字,最后的表达是:

^[\p{L} '.-]+?(?=(?:\s[a-z]+)*\h*$)
测试2 产出2 方法3 我想,我们也可以看看
preg_replace
函数,完全忘记名称,专注于在一行中匹配名称的右侧边界,可能使用类似以下的简单表达式:

(?:\s[a-z]+){0,}\h*$
或:

测试3 产出3 方法4: 也许,这是最简单、最快的方法。在这里,我们将使用贪婪表达式获取行中的最后一个大写字母,然后添加
\S+
\S*

^.*\p{Lu}\S+
或者

或使用数字量词:

^.{0,50}\p{Lu}\S*


如果您希望简化/更新/探索表达式,将在的右上面板中进行解释。如果您感兴趣,可以查看匹配步骤或在中修改它们。调试器演示了如何逐步使用一些示例输入字符串并执行匹配过程

我的名字叫约翰·多伊,你为什么不接受呢?看看匹配所有名字会比你想象的困难得多;看看名字是否保证在字符串的开头,然后别忘了用
^
@Toto通过
John Doe waves
锚定你的正则表达式,意思是这个人的名字是John Doe。@senty你没有抓住要点:如果某人的名字是“John Doe waves”,你的程序会把他们错称为“John Doe”,假设是“waves”不是名称的一部分。一个更合理的例子可能是“约翰辩护第三代”,也可能是第三代名为“约翰辩护”的人,或者是一个关于一个叫约翰的人援引美国宪法第三修正案的标题。或者是一个以“May”开头的句子,可能是名字,也可能不是名字……非常感谢。我会把这些通读一遍你的工作做得很好。我会试着用一个更大的集合来理解你的正则表达式,如果我不能理解一些情况,我会大喊一声(希望没问题)
array(9) {
  [0]=>
  array(1) {
    [0]=>
    string(8) "John Doe"
  }
  [1]=>
  array(1) {
    [0]=>
    string(14) "Bakary N'Diaye"
  }
  [2]=>
  array(1) {
    [0]=>
    string(11) "Dan I Soylu"
  }
  [3]=>
  array(1) {
    [0]=>
    string(18) "Mike van der Hoorn"
  }
  [4]=>
  array(1) {
    [0]=>
    string(13) "M.J. Williams"
  }
  [5]=>
  array(1) {
    [0]=>
    string(17) "Donny van de Beek"
  }
  [6]=>
  array(1) {
    [0]=>
    string(18) "Mike van der Hoorn"
  }
  [7]=>
  array(1) {
    [0]=>
    string(18) "Artak G. Grigoryan"
  }
  [8]=>
  array(1) {
    [0]=>
    string(22) "Trent Alexander-Arnold"
  }
}
(?:\s[a-z]+){0,}\h*$
(?:\s*\b[a-z]+){0,}\h*$
$re = '/(?:\s[a-z]+){0,}\h*$/m';
$str = 'John Doe waves
Bakary N\'Diaye says hello
Iván Aguilar goes well
Cisteró shot
Dan I Soylu shots
Mike van der Hoorn with a cross
M.J. Williams takes a shot
Donny van de Beek left foot
Mike van der Hoorn hello
Artak G. Grigoryan with through ball
Trent Alexander-Arnold after a break ';

echo preg_replace($re, '', $str);
John Doe
Bakary N'Diaye
Iván Aguilar
Cisteró
Dan I Soylu
Mike van der Hoorn
M.J. Williams
Donny van de Beek
Mike van der Hoorn
Artak G. Grigoryan
Trent Alexander-Arnold
^.*\p{Lu}\S+
^.*\p{Lu}\S*
^.{0,50}\p{Lu}\S*