使用 php preg_match_all() 捕获 uuid 后跟 @ 字符

Use php preg_match_all() to capture uuids followed by @ character

如何使用 preg_match_all() 获取以下字符串中的 1a1a-1a1a2B2B2-B2 :

$string  = 'Hello @1a1a-1a1a and @2B2B2-B2 too';

我的目标是捕获每个 @ 后跟一个 uuid。

我试过了:

preg_match_all("/@(.*)/", $string, $matches);
preg_match_all("/@.*?/U", $string, $matches);
preg_match_all("/@([^\"]+)/si", $a, $matches);

但是没能做到

使用 /(?<=@)[\w-]+/ 模式匹配 @

之后的任何字符串
preg_match_all("/(?<=@)[\w-]+/", $string, $matches);
print_r($matches[0]);

输出

Array
(
    [0] => 1a1a-1a1a
    [1] => 2B2B2-B2
)

检查结果 demo

你的正则表达式匹配:

  • @(.*) 匹配 @ 并在组中捕获任何字符 0+ 次贪婪,包括 space 将匹配您示例中的所有字符
  • @.*? 匹配 @ 后跟任何字符 0+ 次非贪婪,它只会匹配 @
  • @([^\"]+) 匹配 @ 并在组中捕获匹配而不是 " 将匹配您示例中的所有内容

要捕获每个 @ 后跟一个 uuid,您可以使用 character class 列出您允许匹配的内容,并在非捕获组中重复以破折号开头的模式 1+次。

如果只想匹配 uuid,可以在捕获组中捕获值。

@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+)

Regex demo

$string  = 'Hello @1a1a-1a1a and @2B2B2-B2 too';
preg_match_all("/@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)+)/", $string, $matches);
print_r($matches[1]);

结果

Array
(
    [0] => 1a1a-1a1a
    [1] => 2B2B2-B2
)

Demo php

@(.*) 正则表达式匹配 @ 并且贪婪地匹配任何 0 个或多个字符而不是换行字符(即该行的其余部分)。 /@.*?/U是一个同义模式,它等同于/@.*/,只是@之后的文本不被抓取到一个组中。 @([^\"]+) 匹配 @ 并将 " 以外的任何一个或多个字符捕获到第 1 组中,如果没有,则匹配到第一个 " 或字符串结尾".

我建议使用

preg_match_all('~@\K[\w-]+~', $s, $matches)

参见regex demo@\K[\w-]+ 将匹配 @\K 将其从匹配中删除,[\w-]+ 将匹配 1 个或多个单词或将返回的 - 个字符。

为了使模式更具限制性,例如,只匹配 @ 之后可以用连字符分隔的字母或数字,您可以使用

'~@\K[A-Z0-9]+(?:-[A-Z0-9]+)*~i'

参见 this regex demo。此处,[A-Z0-9]+ 匹配 1 个或多个字母数字字符,而 (?:-[A-Z0-9]+)* 将匹配 0 次或多次重复的 - 后跟 1+ 个字母数字字符。 i 修饰符将使模式不区分大小写。

试试这个,无论有多少个字符,它都会捕获“@”之后的所有内容

preg_match_all("@(\w)*/", $string, $matches)