PHP preg_match returns 两场比赛而不是一场

PHP preg_match returns two matches instead of one

我有这个字符串:ATL.556808.UMO20.02 我只想得到 UMO20.02.

这是我的 preg_match:

$e = preg_match('"\.[^\.]+\.(.*?)$"si', $t, $m);

但是这段代码 return 匹配了两个而不是一个。我得到了:

array(2) {  
 [0]=>   string(16) ".556808.UMO20.02"  
 [1]=>   string(8) "UMO20.02" 
}

但我想要一场比赛:

array(1) { 
 [0]=>   string(8) "UMO20.02" 
}

问题出在哪里?

您的 \.[^\.]+\.(.*?)$ 正则表达式匹配 .,然后是除点以外的任何一个或多个字符,然后是点,然后是尽可能少的任何零个或多个字符(但完成匹配 ) 到字符串末尾所需的数量。 .*? 必须 调整 以匹配除点以外的任何字符。

要删除第二个点之前的所有内容,您可以使用

$t = 'ATL.556808.UMO20.02';
echo preg_replace('~^(?:[^.]+\.){2}~', '', $t);
// => UMO20.02

PHP demo. See the regex demo详情:

  • ^ - 字符串开头
  • (?:[^.]+\.){2} - 除了 .. 字符
  • 之外的任何一个或多个字符出现两次

您不必使用 si 标志,因为大写或小写字符没有特定的大小写,并且点不必匹配示例中的换行符数据。

您可以使用

\.[^.]+\.\K.+$
  • \. 匹配 .
  • [^.]+\. 匹配除 .
  • 之外的任何字符 1+ 次
  • \K忘记匹配的是什么
  • .+ 匹配任意字符 1+ 次
  • $ 字符串结束

Regex demo

示例代码

$re = '/\.[^.]+\.\K.+$/';
$str = 'ATL.556808.UMO20.02';

preg_match($re, $str, $matches);

print_r($matches);

输出

Array
(
    [0] => UMO20.02
)