BEGINNER: REGEX Соответствует числовой последовательности, кроме случаев, когда в строке присутствует слово «CODE». - PullRequest
1 голос
/ 23 декабря 2009

В течение довольно длительного времени мне удавалось пробираться по регулярным выражениям, но, увы, я не могу помочь нуждающемуся другу.

Мой "друг" пытается сопоставить все строки в текстовом файле, которые соответствуют следующим критериям:

  1. Только 7-10-значный номер (0123456 или 0123456789)
  2. Только 7-10-значный номер, затем тире, затем еще две цифры (0123456-01 или 0123456789-01)
  3. Соответствует любому из вышеперечисленных , за исключением , где слова Код / код или Пароль / код доступа перед совпадающими числами (например, «Код доступа: 16434629» или «Пароль 5253443» -12" )
  4. РЕДАКТИРОВАТЬ : нужны только совпадающие числа, ничего больше.

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

^(?=.*?[^=/%:]\b\d{7,10}((\d?\d?)|(-\d\d))?\b)((?!Passcode|passcode|Code|code).)*$

...

Вопрос : Есть ли способ использовать короткое регулярное выражение, чтобы найти все строки, которые соответствуют вышеуказанным критериям?

Предположим, PCRE. Мой друг заранее благодарит тебя. ; -)

Кстати, я не смог найти другие вопросы, перечисленные в stackoverflow.com или superuser.com, которые могут точно ответить на этот вопрос.

РЕДАКТИРОВАТЬ : Я использую Kodos Python Regex Debugger для проверки и тестирования регулярных выражений.

Ответы [ 2 ]

4 голосов
/ 23 декабря 2009
(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?

Комментируемая версия:

(?<!                 # Begin zero-width negative lookbehind. (Makes sure the following pattern can't match before this position)
(?:                  # Begin non-matching group
[Pp]asscode          # Either Passcode or passcode
|                    # OR
[Cc]ode              # Either Code or code
)                    # End non-matching group
.*                   # Any characters
)                    # End lookbehind
[0-9]{7,10}          # 7 to 10 digits
(?:                  # Begin non-matching group
-[0-9]{2}            # dash followed by 2 digits
)                    # End non-matching group
?                    # Make last group optional

Редактировать: окончательная версия после обсуждения комментариев -

/^(?!\D*(?:[Pp]asscode|[Cc]ode))\D*([0-9]{7,10}(?:-[0-9]{2})?)/

(результат в первом буфере захвата)

1 голос
/ 24 декабря 2009

Вы можете справиться с неприятным регулярным выражением, с которым вам нужно получить помощь ...

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

Что бы вы хотели прочитать?

$foo =~ /(?<!(?:[Pp]asscode|[Cc]ode).*)[0-9]{7,10}(?:-[0-9]{2})?/

или

$foo =~ /\d{7,10}(-\d{2})?/ and $foo !~ /(access |pass)code/i;

Редактировать: без учета регистра.

...