Я пытаюсь выяснить синтаксис регулярного выражения, которое соответствовало бы 4 буквенно-цифровым символам, где есть хотя бы одна буква. Каждый должен быть заключен в: >
и <
, но я бы не хотел возвращать угловые скобки.
Например, при использовании re.findall
в строке >ABCD<>1234<>ABC1<>ABC2
он должен вернуть ['ABCD', 'ABC1']
.
1234
- без буквы
ABC2
- без угловых скоб
Часть, с которой у меня проблема, - это «хотя бы одна буква» и «не возвращаются скобки». Без этих двух требований это довольно просто: r'(>[A-Z0-9]{4}<)'
Я не уверен, что это вообще возможно с регулярным выражением, не так ли?
Вы говорите, что хотите сопоставить ['ABCD', 'ABC4']
из вашей примерной строки. Но в вашем примере строка не содержит «ABC4». Это опечатка? Если нет, просьба подробнее рассказать о задействованной бизнес-логике.
@Kevin - извините за опечатку, я отредактировал пост, чтобы исправить
Вы можете использовать это регулярное выражение на основе опережающего просмотра в Python с findall
:
(?i)>((?=\d*[a-z])[a-z\d]{4})<
Код:
>>> regex = re.compile(r">((?=\d*[a-z])[a-z\d]{4})<", re.I)
>>> s = ">ABCD<>1234<>ABC1<>ABC2"
>>> print (regex.findall(s))
['ABCD', 'ABC1']
Детали RegEx:
re.I
: включить модификатор игнорирования регистра>
: соответствует буквальному символу >
(
: Начать группу захвата
(?=\d*[a-z])
: посмотрите вперед, чтобы убедиться, что у нас есть хотя бы одна буква после 0 или более цифр[a-z\d]{4}
: соответствие 4 буквенно-цифровых символов)
: Конечная группа захвата<
: соответствует буквальному символу <
не было бы лучше скомпилировать регулярное выражение и добавить инказитивный флаг в качестве второго аргумента вместо того, чтобы делать строку регулярного выражения длиннее?
Работал как шарм! Не могли бы вы уточнить синтаксис?
@YannicHamann: Хорошая идея, добавили re.compile
в код.
@MJB: Я добавил подробное объяснение регулярного выражения в свой ответ. Дайте мне знать, какая часть не ясна, и я добавлю больше деталей.
@MJB: нажмите на демонстрацию и прочтите правую сторону. У него более подробное объяснение. Затем прочтите документы по регулярным выражениям, чтобы узнать, что не имеет смысла. Ключевым моментом здесь является утверждение опережения (?=\d*[a-z])
(опережающее утверждение начинается с ?=
). Он что-то утверждает о следующих персонажах, не поглощая их.
Спасибо @StevenRumbalski за то, что поправил меня. Мне нужно сейчас проверить глаза :)
import re
sentence = ">ABCD<>1234<>ABC1<>ABC2"
pattern = "\>((?=[a-zA-Z])(.){4})\<"
m = [m[0] for m in re.findall(pattern, sentence)]
#outputs ['ABCD', 'ABC1']
Некоторое объяснение может быть полезно здесь
И какое ваше регулярное выражение вы сделали: /?