Динамическое регулярное выражение - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть вход, который выглядит следующим образом

[d/D/d1/d2/d3/d4/d5/d6/d7/D1/D2/D3/D4/D5/D6/D7]+[\.]+[r1/r2/r3/r4/r5/r6/R1/R2/R3/R4/R5/R6]+[\.]+[number 1 to 37]+[#]+[number 0 - 9 ]

Примером может быть "d2.r1.4 # 100.37 # 1.9 # 2.3 # 1 (может иметь столько 1-37 # 0-9при необходимости) "

Как мне написать соответствие регулярному выражению, которое может позволить последней части строки быть динамической (сопоставляет столько групп, сколько необходимо, сколько введено)

Я пробовал этовыражение:

[dD1-7]+\.[rR1-5]+\. 

и я не уверен, как сопоставить динамическую группу, которая идет после "d2.r1".часть.

Ответы [ 3 ]

1 голос
/ 26 сентября 2019

Предполагая, что вам просто нужно проверить строку (а не захватывать / извлекать определенные подстроки), следующий шаблон дает тот же результат, что и ответ Эммы, но с более строгим синтаксисом.

Модификатор шаблона i означаетВам нужно всего лишь написать две буквы в нижнем регистре.Я не использую лишние группы без захвата.Двухсимвольные классы символов не нуждаются в дефисе.\d является более коротким способом выражения [0-9].

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

Код: ( Демо )

$inputs = [
    'd2.r1.4#100.37#1.9#2.3#1',
    'd2.r1.4#100.37#1.9#2.38#1.8#22',
    'd2.r1.4#100.37#1.9#2.3#1.12#2.30#2',
];

$pattern = '/^d[1-7]\.r[1-6](?:\.(?:3[0-7]|[12]\d|[1-9])#\d+)*$/i';

foreach ($inputs as $input) {
    echo "\n{$input}: ";
    var_export((bool)preg_match($pattern, $input));
}

Выход:

d2.r1.4#100.37#1.9#2.3#1: true
d2.r1.4#100.37#1.9#2.38#1.8#22: false
d2.r1.4#100.37#1.9#2.3#1.12#2.30#2: true
0 голосов
/ 26 сентября 2019

С вложенными группами:

^[dD][1-7]\.[rR][1-5]\.\d?(#\d+(?:\.(?:3[0-7]|[1-2][0-9]|[1-9]))?)+

Первый сегмент (включая первый \.\d) + Группы: хэш + число (необязательно с десятичной).

0 голосов
/ 25 сентября 2019

Я предполагаю, что, возможно, какое-то выражение, похожее на

^[dD][1-7]\.[rR][1-6](?:(?:\.(?:3[0-7]|[1-2]\d|[1-9]))#[0-9]+)*$

или с некоторыми небольшими изменениями, скорее всего будет работать здесь.

Test

$re = '/^[dD][1-7]\.[rR][1-6](?:(?:\.(?:3[0-7]|[1-2]\d|[1-9]))#[0-9]+)*$/m';
$str = 'd2.r1.4#100.37#1.9#2.3#1
d2.r1.4#100.37#1.9#2.3#1.37#1.9#2.3#1.37#1.9#2.3#1.37#1.9#2.3#1
d2.r1.4#100.38#1.9#2.3#1
d2.r1.4#100.0#1.9#2.3#1
';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

var_dump($matches);

Вывод

array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(24) "d2.r1.4#100.37#1.9#2.3#1"
  }
  [1]=>
  array(1) {
    [0]=>
    string(63) "d2.r1.4#100.37#1.9#2.3#1.37#1.9#2.3#1.37#1.9#2.3#1.37#1.9#2.3#1"
  }
}

Если вы хотите упростить / изменить / изучить выражение, это было объяснено на верхней правой панели regex101.com .Если хотите, вы также можете посмотреть в эту ссылку , как она будет сопоставляться с некоторыми примерами входных данных.


RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

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