Задача регулярного экспресс-поиска шаблонов поиска совпадений - PullRequest
1 голос
/ 09 июля 2019

У меня одна из четырех скороговорок:

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

Можно ли получить "Тест" с помощью одного preg_match вызова?

Я попробовал следующее:

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

... но это возвращает мне пять элементов $matches назад. Но я хотел бы иметь только два (один для всего совпадения и один для найденного совпадения с "Test" в нем.)

Ответы [ 4 ]

2 голосов
/ 09 июля 2019

Вы можете использовать точку для сопоставления символов вокруг слова и использовать 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 голос
/ 09 июля 2019

Чтобы убедиться, что одинарная кавычка, обратная галочка и двойная кавычка и одинаковый закрывающий символ, вы можете использовать группу захвата с обратной ссылкой к этой группе.

Чтобы та же группа в чередовании также соответствовала ( с закрывающим ), вы можете использовать группу сброса ветви .

Соответствие Test находится в группе 2

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

Пояснение

  • (?| Группа сброса ветви
    • (["'`]) Захват в группе 1любой из перечисленных
    • (Test)\1 Захват в группе 2 Соответствующий тест с последующей обратной ссылкой \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
0 голосов
/ 09 июля 2019

Ваше регулярное выражение может быть:

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

Что выдаст следующий код в PHP:

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

Объяснение

В Regex группы символов, отмеченные квадратными скобками [], соответствуют одному из символов внутри него.

0 голосов
/ 09 июля 2019

Вы можете использовать группы без захвата:

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

Так что только группа (. *) Будет собирать данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...