Regex, как подобрать дополнительный символ

147

У меня есть регулярное выражение, которое я думал, работает правильно до сих пор. Мне нужно сопоставить дополнительный символ. Это может быть там или не может.

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

Я хотел бы получить одну букву после начальных 5 цифр, если она есть, а если нет, продолжить получать оставшуюся строку. Это письмо может быть A-Z.

Если я удалю ([A-Z]{1}) +.*? +из регулярного выражения, он будет соответствовать всем, что мне нужно, кроме буквы, но это важно.

20000      K               Q511195DREWBT            E00078748521
30000                      K601220PLOPOH            Z00054878524

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

/^([0-9]{5})+.*? ([A-Z]{1}) +.*? +([A-Z]{1})([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3}) +([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})/
Джим
источник

Ответы:

247

использование

[A-Z]?

сделать письмо необязательным. {1}избыточно (Конечно, вы могли бы написать, [A-Z]{0,1}что означало бы то же самое, но это то, что нужно ?.)

Вы могли бы улучшить свое регулярное выражение для

^([0-9]{5})+\s+([A-Z]?)\s+([A-Z])([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})

И, поскольку в большинстве диалектов регулярных выражений, \dэто то же самое, что и [0-9]:

^(\d{5})+\s+([A-Z]?)\s+([A-Z])(\d{3})(\d{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])\d{3}(\d{4})(\d{2})(\d{2})

Но: вам действительно нужно 11 отдельных групп захвата? И если так, то почему бы вам не захватить четвертую или последнюю группу цифр?

Тим Питцкер
источник
Тим, я, честно говоря, не уверен, поскольку я не писал это регулярное выражение. Я все еще довольно новичок в регулярных выражениях. Если вы видите лучший способ написать это, я открыт для предложений.
Джим
1
Тим, твой пример работает для обеих строк, есть ли у меня буква в этой позиции или нет. Спасибо.
Джим
26

Вы можете сделать одну букву необязательной, добавив ?после нее как:

([A-Z]{1}?)

Квантификатор {1}является избыточным, поэтому вы можете удалить его.

codaddict
источник
Спасибо кодекдикт. Знак вопроса заменяет `+. *? + `?
Джим
При использовании grep regex вы получите ошибку, если опустите {1} (утверждение grep: lookbehind не имеет фиксированной длины). Так что это дело для ухода его.
Zunderscore
6

Вы также должны пометить одну букву как дополнительную:

([A-Z]{1})? +.*? +

или сделать всю часть необязательной

(([A-Z]{1}) +.*? +)?
Стефан
источник
1
Стефан, я хотел бы сделать письмо совершенно необязательным. Я попробовал оба из них, но это все еще ничего не соответствует. Я уверен, что я неправильно понял. Не могли бы вы изменить свой пример, чтобы включить его в строку?
Джим
0

Вы также можете использовать более простое регулярное выражение, разработанное для вашего случая, например, (.*)\/(([^\?\n\r])*)где $2соответствовать тому, что вы хотите.

robinvrd
источник