Извлечение слова, соответствующего определенным критериям - PullRequest
2 голосов
/ 25 июня 2011

У меня есть следующая строка:

SEDCVBNT S800BG09 7GFHFGD6H 324235346 RHGF7U S8-00BG / 09 7687678

и следующее регулярное выражение:

preg_match_all('/\b(?=.+[0-9])(?=.+[A-Z])[A-Z0-9-\/]{4,20}/i', $string, $matches)

То, чего я пытаюсь добиться, это вернуть все «слова», которые:

  • содержат хотя бы 1 цифру
  • содержат хотя бы 1 букву
  • можетсодержать '/'
  • может содержать '-'

К сожалению, вышеприведенное регулярное выражение возвращает:

Array ( [0] => Array ( [0] => SEDCVBNT [1] => S800BG09 [2] => 7GFHFGD6H [3] => 324235346 [4] => RHGF7U [5] => S8-00BG/09 ) ) 

Я не хочу 'SEDCVBNT' или '324235346 ', чтобы быть возвращенным.

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

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 25 июня 2011

Для этого вам понадобится немного продвинутый синтаксис регулярных выражений.

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

(?<=\s|^)(?=[\w/-]*\d[\w/-]*)(?=[\w/-]*[A-Za-z][\w/-]*)([\w/-])+(?=\s|$)

Давайте объясним это:

  • Синтаксис [\w/-] часто встречается; это означает «любой символ слова (который включает буквы, цифры, акцентированные буквы и т. д.) или косую черту или тире» - фактически все символы, которые вы считаете частью действительного токена.
  • Регулярное выражение использует положительный прогноз, чтобы убедиться, что в том месте, где предпринята попытка сопоставления, следующий текст удовлетворяет определенным критериям Позитивный взгляд выглядит так: (?=[\w/-]*\d[\w/-]*).
  • Он также использует положительный (тот, что в конце: (?=\s|$)) и отрицательный (в начале: (?<=\s|^)) прогноз, чтобы убедиться, что сопоставление выполняется только в том случае, если весь текстовый токен начинается после символа пробела или находится в начале входной строки (\s|^) и сопровождается символом пробела или завершает строку ввода (\s|$).
  • Поскольку два внутренних шаблона предпросмотра практически идентичны шаблону группы захвата ([\w/-])+, фактически я использую их для сопоставления только с текстом, который соответствует нескольким шаблонам: оба элемента прогнозирования и шаблон группы захвата в конце.
  • Первый просмотр гарантирует, что в следующем токене будет хотя бы одна цифра (\d).
  • Второй запрос гарантирует, что в следующем токене будет хотя бы одна буква (A-Za-z).
  • Группа захвата соответствует одному или нескольким символам слова и / или / и -.

Поэтому, чтобы группа захвата соответствовала, проверяемый текст должен:

  1. Предваряется пробелом или началом входной строки (это предотвращает совпадение частичных слов после запрещенного символа)
  2. Включить по крайней мере одну цифру в следующем ряду разрешенных символов (первый положительный взгляд)
  3. Включите хотя бы одну букву в следующую строку разрешенных символов (второй положительный взгляд)
  4. Состоит только из символов слова / и - (группа захвата).
  5. За ним следует либо пробел, либо конец входной строки (это предотвращает совпадение частичных слов с запрещенным символом).

Что именно вам нужно. :)

Смотрите это в действии!

Примечание: refiddle.com, похоже, не очень хорошо работает с негативным lookbehind, поэтому регулярное выражение после ссылки не включает начальную часть (?<=\s|^). Это означает, что он будет ошибочно соответствовать DEF456 в ABC123$DEF456.

0 голосов
/ 25 июня 2011

Вот необработанное регулярное выражение: \b(?=\S*?\d)(?=\S*?[a-z])\S+?(?=$|\s)

preg_match_all('/\b(?=\S*?\d)(?=\S*?[a-z])\S+?(?=$|\s)/i', $string, $matches) 
...