Можно ли это сделать за одно регулярное выражение? - PullRequest
6 голосов
/ 03 декабря 2010

Мне нужно регулярное выражение для соответствия строке, которая:

  • имеет только цифры 0-9 и пробелы
  • все цифры должны быть одинаковыми
  • должно иметь место впо крайней мере 2 цифры
  • должны начинаться и заканчиваться цифрами

Совпадения:

11
11111
1  1 1 1 1
1  1
11 1 1 1 1 1
1           1
1    1      1

Нет совпадений:

1             has only one digit
11111         has space at the end
 11111        has space at beginning
12            digits are different
11:           has other character

Я знаюрегулярное выражение для каждого моего требования.Таким образом, я буду использовать 4 теста регулярных выражений.Можем ли мы сделать это в одном регулярном выражении?

Ответы [ 4 ]

14 голосов
/ 03 декабря 2010

Да, это можно сделать за одно регулярное выражение:

^(\d)(?:\1| )*\1$

Рубулярная ссылка

Пояснение:

^      - Start anchor
(      - Start parenthesis for capturing
 \d    - A digit
)      - End parenthesis for capturing
(?:    - Start parenthesis for grouping only
\1     - Back reference referring to the digit capture before
|      - Or
       - A literal space
)      - End grouping parenthesis
*      - zero or more of previous match
\1     - The digit captured before
$      - End anchor
2 голосов
/ 03 декабря 2010

Рассмотрим эту программу:

#!/usr/bin/perl -l
$_ = "3 33 3 3";
print /^(\d)[\1 ]*\1$/      ? 1 : 0;
print /^(\d)(?:\1| )*\1$/   ? 1 : 0;

Она производит вывод

0
1

Ответ очевиден, если вы посмотрите на скомпилированные регулярные выражения:

perl -c -Mre=debug /tmp/a
Compiling REx "^(\d)[\1 ]*\1$"
synthetic stclass "ANYOF[0-9][{unicode_all}]".
Final program:
   1: BOL (2)
   2: OPEN1 (4)
   4:   DIGIT (5)
   5: CLOSE1 (7)
   7: STAR (19)
   8:   ANYOF[\1 ][] (0)
  19: REF1 (21)
  21: EOL (22)
  22: END (0)
floating ""$ at 1..2147483647 (checking floating) stclass ANYOF[0-9][{unicode_all}] anchored(BOL) minlen 1 
Compiling REx "^(\d)(?:\1| )*\1$"
synthetic stclass "ANYOF[0-9][{unicode_all}]".
Final program:
   1: BOL (2)
   2: OPEN1 (4)
   4:   DIGIT (5)
   5: CLOSE1 (7)
   7: CURLYX[1] {0,32767} (17)
   9:   BRANCH (12)
  10:     REF1 (16)
  12:   BRANCH (FAIL)
  13:     EXACT < > (16)
  15:   TAIL (16)
  16: WHILEM[1/1] (0)
  17: NOTHING (18)
  18: REF1 (20)
  20: EOL (21)
  21: END (0)
floating ""$ at 1..2147483647 (checking floating) stclass ANYOF[0-9][{unicode_all}] anchored(BOL) minlen 1 
/tmp/a syntax OK
Freeing REx: "^(\d)[\1 ]*\1$"
Freeing REx: "^(\d)(?:\1| )*\1$"

Обратные ссылки - это обычные восьмеричные символы внутри классов символов !!

1 голос
/ 06 декабря 2010
^(\d)( *\1)+$


0 голосов
/ 06 декабря 2010
/^(\d)(\1| )*\1$/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...