0

这是我的模式:

$fullname = '/^([a-zA-Z]+)(?:[,]?[\s]?)?([a-zA-Z]+)((?:\s)([a-zA-Z]{1}))?$/i';

preg_match($nameReg, $value, $match)在 PHP 中使用它。

我想捕获姓氏,然后是名字。由于我将使用 ajax 在我的 sql 语句中通过 LIKE 动态加载结果,因此我想从姓氏开始,而不是等待名字。

问题是,当我只输入姓氏(第一个单词)时,我将姓氏的最后一个字符作为捕获的组。

Array
(
    [0] => SMITH
    [1] => SMIT
    [2] => H
)

我想得到

Array
(
    [0] => SMITH
    [1] => SMITH
)

但我不明白这里发生了什么。

4

1 回答 1

2

那是因为您在第二个中至少需要一个字母[a-zA-Z]+。如果您将第二个捕获组设为可选,它应该可以工作:

/^([a-zA-Z]+)(?:[,]?[\s]?)?([a-zA-Z]+)?((?:\s)([a-zA-Z]{1}))?$/i

但是,您正在使用不区分大小写的标志,但仍提供大写和小写变体。加号{1}总是多余的。最后,单字符字符类也是不必要的,虽然这可能是一个品味问题,但我认为它们只会帮助需要转义的空格和字符的可读性。这可以缩短:

/^([a-z]+)(?:,?\s?)?([a-z]+)?((?:\s)([a-z]))?$/i

也许嵌套一些可选组也是一个好主意。例如,如果没有逗号或空格来分隔第二个名称,则没有理由允许使用第二个名称:

/^([a-z]+)(?:(?:,\s?|\s)([a-z]+)?)?(?:\s([a-z]))?$/i
于 2012-11-08T16:58:45.767 回答