Регулярное выражение, удовлетворяющее нескольким условиям

#python #regex

#python #регулярное выражение

Вопрос:

Используя python, я пытаюсь определить строки, которые проверяют следующие условия:

  1. Оно должно содержать 9 символов
  2. Символы от 2 до 8 должны быть числами
  3. Символы 1 и 9 могут быть цифрами или буквами (нижними или верхними)
  4. Символы 1 и 9 не могут быть одновременно числами.

Например, ‘A12345678’, ‘01234567A’ и ‘A1234567B’ будут совпадать, но ‘012345678’ не будет совпадать.

Для условий с 1 по 3 я использую '([a-z]|[A-Z]|[0-9])[0-9]{7}([a-z]|[A-Z]|[0-9])$' . Для условия 4 я использую '(?![0-9]{9}$)' . Однако я не знаю, как объединить эти условия в уникальное регулярное выражение. Кто-нибудь может мне помочь? Заранее спасибо!

Комментарии:

1. Я допустил ошибку, извините. Условие 4 заключается в том, что они не могут быть обоими числами

Ответ №1:

Разделите два случая (буква спереди / буква сзади)

 ^([A-Z][0-9]{7}[A-Z0-9]|[A-Z0-9][0-9]{7}[A-Z])$
 

Применяется с флагом «без учета регистра».

Комментарии:

1. Спасибо, это работает! Но добавление этого 1-го и последнего может быть обеими буквами '^([A-Z][0-9]{8}|[0-9]{8}[A-Z]|[A-Z][0-9]{7}[A-Z])$'

2. @JN_2605 О, это верно. Смотрите обновленный ответ.

Ответ №2:

В качестве альтернативы, вы могли бы попробовать:

 ^(?=D?d{7,8}D?$)[A-Zd]{9}
 

Смотрите онлайн-демонстрацию

  • ^ — Запуск привязки строки.
  • (?= — Откройте позитивный прогноз.
    • D? — Необязательный нецифровый.
    • d{7,8} — 7 или 8 цифр.
    • D? — Необязательный нецифровый.
    • $) — Завершите привязку строки и закройте положительный прогноз.
  • [A-Zd]{9} — 9 символов из заданного класса.

Или, предполагая проверку одной строки, вы могли бы попробовать:

 ^(?!d{9}|.*_|. D.)w{9}$
 
  • ^ — Запуск привязки строки.
  • (?! — Открыть отрицательный прогноз:
    • d{9} — Девять цифр.
    • | — Или:
    • .*_ — Любое подчеркивание в любом месте строки.
    • | — Или:
    • . D. — Любой символ 1 , за которым следует не цифра и другой символ.
    • ) — Закрыть отрицательный прогноз.
  • w{9} — Девять символов слова.
  • $ — Конец привязки строки.

Комментарии:

1. Это умно, мне это нравится. 🙂

Ответ №3:

Это

  r"^((?:[0-9]{8})(?:[a-z]|[A-Z])|(?:[a-z]|[A-Z])(?:[0-9]{8})|(?:[a-z]|[A-Z])[0-9]{7}(?:[a-z]|[A-Z]))$"

 # or with ignore case
 r"^([0-9]{8}[a-z]|[a-z][0-9]{8}|[a-z][0-9]{7}[a-z])$"
 

будет соответствовать

 (?:[0-9]{8})(?:[a-z]|[A-Z])             # 8 numbers   letter
(?:[a-z]|[A-Z])(?:[0-9]{8})             # letter   8 numbers
(?:[a-z]|[A-Z])[0-9]{7}(?:[a-z]|[A-Z])  # letter   7 numbers   letter
 

Вы можете уменьшить его с помощью re.I флага для нечувствительности к регистру.

Я заменил группы захвата на группы без группировки.

Демонстрация: https://regex101.com/r/Nr5wus/3 и https://regex101.com/r/bypoGq/2 (игнорировать регистр)

Ответ №4:

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

 ^(?:([A-Z])|[0-9])[0-9]{7}(?(1)[A-Z0-9]|[A-Z])$
 

Смотрите демонстрацию регулярных выражений.

Подробные сведения:

  • ^ — начало строки
  • (?:([A-Z])|[0-9]) — либо буква (записанная в группе 1), либо цифра
  • [0-9]{7} — семь цифр
  • (?(1)[A-Z0-9]|[A-Z]) — если группа 1 соответствует, сопоставьте букву или цифру, иначе сопоставьте только букву
  • $ — конец строки.