посмотрите вперед на нецифровые символы

#java #regex

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

Вопрос:

У меня есть regex , который должен извлекать номерные знаки из текста. Например, он должен иметь возможность извлекать D-D 200 , A-DEÜ34 , A-DEÜ34 и D-D200 из следующих наборов символов:

 1) D-D 200
2) A-DEÜ34.
3) A-DE34 on the fly
4) D-D200 my name is blah blah
 

но следующий номер не является приемлемым номерным знаком, и извлечение D-D 200 из следующего текста неверно:

 1) D-D 200 200
 

Что я пытаюсь сделать в своем регулярном выражении, так это заглянуть вперед и проверить, являются ли следующие символы «пробелом и нецифровым». Но, похоже, мой код работает неправильно.

Вот мое регулярное выражение:

 //      between one to three letters:   [a-züäöA-ZÜÄÖ]){1,3})
//      a dash line                     -   or a \—
//      between one to three letters:   [a-zA-Z]){1,3}
//      zero or one space               (s){0,1}
//      one to four letters             ([0-9]){1,4}
//      look ahead (?=)
//      look ahead for: space AND a non digit   sD
//              or dot or comma .|,
(([a-züäöA-ZÜÄÖ]){1,3})(-|—)([a-züäöA-ZÜÄÖ]){1,3}((s){0,1})([0-9]){1,4}(?=(sD|.|,))
 

Любая помощь будет оценена.

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

1. Почему standalone D-D 200 хорош, но извлекает его из D-D 200 200 плохого?

2.Это сработало бы ^b[a-zA-Z]{1,3}-[a-zA-Z]{1,3} ?d{1,4}b(?=[ .]D|$) regex101.com/r/i9aYAy/1

Ответ №1:

Если вы утверждаете, что справа должны быть не цифры (за исключением случаев, когда есть новая строка), тогда первый пример D-D 200 не будет соответствовать сам по себе, поскольку после него нет символа для утверждения.

Обратите внимание, что (sD|.|,) это то же (D) D самое, что и совпадения с нецифровыми символами, но если вам не нужны группы захвата, вы можете их опустить.


Вы можете использовать отрицательный (?![^drn]*d) прогноз, чтобы утверждать, что после шаблона не следует цифра.

 [a-züäöA-ZÜÄÖ]{1,3}[-—][a-züäöA-ZÜÄÖ]{1,3}s?[0-9]{1,4}(?![^drn]*d)
 

Демонстрация регулярных выражений

Положительным вариантом (?=[^drn]*$) прогноза может быть утверждение, что то, что находится непосредственно справа, не является цифрами до конца строки

 [a-züäöA-ZÜÄÖ]{1,3}[-—][a-züäöA-ZÜÄÖ]{1,3}s?[0-9]{1,4}(?=[^drn]*$)
 

Демонстрация регулярных выражений

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

1. Большое вам спасибо за ваше объяснение и регулярное выражение. Это работает лучше, чем у меня, но это все еще не совсем правильно. Это не работает для «pi-az 4415 lotende 33». Причина в том, что в следующем слове (словах) есть цифра.

2. В то же время, можно ли в любом случае разрешить разрыв строки везде, где в данной строке. Например, я хотел бы иметь возможность правильно распознать «pi-az 4415» в следующей строке: «pi-az 4415 lotende 33».

3.@user13578 Вы имеете в виду вот так? [a-züäöA-ZÜÄÖ]{1,3}[-—][a-züäöA-ZÜÄÖ]{1,3}s?[0-9]{1,4}(?!h*d) regex101.com/r/t9HyJD/1 Или наоборот [a-züäöA-ZÜÄÖ]{1,3}[-—][a-züäöA-ZÜÄÖ]{1,3}s?[0-9]{1,4}(?=h*[^sd]|$) regex101.com/r/iqCcKY/1