问题常规表达模式狩猎相似比赛

时间:2019-07-09 10:52:26

标签: php regex

我有四个模式之一:

"Test"
'Test'
`Test`
(Test)

是否可以通过单个preg_match调用获得“测试”?

我尝试了以下操作:

if ( preg_match( '/^(?:"(.*)"|\'(.*)\'|`(.*)`|\((.*)\')$/iu', $pattern, $matches ) )

...但是这给了我$matches的五个要素。但是我只想有两个(一个用于整个比赛,一个用于带有“测试”的找到的比赛。)

4 个答案:

答案 0 :(得分:2)

您可以使用点匹配单词周围的字符,并使用array_unique删除重复项。

preg_match_all("/.(\w+)./", $str,$match);
foreach($match as &$m) $m = array_unique($m);

var_dump($match);

https://3v4l.org/T2hnh

array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(6) ""Test""
    [1]=>
    string(6) "'Test'"
    [2]=>
    string(6) "`Test`"
    [3]=>
    string(6) "(Test)"
  }
  [1]=>
  &array(1) {
    [0]=>
    string(4) "Test"
  }
}

答案 1 :(得分:1)

为确保单引号,反引号和双引号并具有相同的结束字符,您可以使用捕获组,并在该组中使用backreference

要在轮换中获得相同的组,以使(与结尾的)相匹配,您可以使用branch reset group

Test的匹配项在第2组

(?|(["'`])(Test)\1|\(((Test)\)))

说明

  • (?|分支重置组
    • (["'`])在第1组中捕获任何列出的
    • (Test)\1在第2组匹配的Test中捕获,然后向第1组进行反向引用\1
    • |
    • \(((Test)\))匹配(,在第2组匹配Test中捕获,后跟)
  • )关闭分支重置组

Regex demo | Php demo

例如:

$strings = [
    "\"Test\"",
    "'Test'",
    "`Test`",
    "(Test)",
    "Test\"",
    "'Test",
    "Test`",
    "(Test",
    "\"Test'",
    "'Test\"",
    "`Test",
    "Test)",
];
$pattern = '/(?|(["\'`])(Test)\1|\(((Test)\)))/';
foreach ($strings as $string){
    $isMatch = preg_match($pattern, $string, $matches);
    if ($isMatch) {
        echo "Match $string ==> " . $matches[2] . PHP_EOL;
    }
}

结果

Match "Test" ==> Test
Match 'Test' ==> Test
Match `Test` ==> Test
Match (Test) ==> Test

答案 2 :(得分:0)

您可以使用非捕获组:

 '/^(?:"|\'|`|\()(.*)(?:"|\'|`|\))$/iu'

所以只有(。*)组将捕获数据。

答案 3 :(得分:0)

您的正则表达式可能是:

^['"`(](.+)['"`)]$

哪个会在PHP中释放以下代码:

if(preg_match('^[\'"`(](.+)[\'"`)]$', $pattern, $matches))

说明

在Regex中,用括起来的方括号[]标记的字符组与其中的一个字符匹配。