Сопоставьте несколько вхождений или ноль (в этом порядке) с помощью регулярных выражений - PullRequest
3 голосов
/ 18 октября 2010

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

/M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})/

Проблема в том, что выражение типа /V?I{0,3}/ не является жадным в Groovy. Поэтому для такой строки, как «Книга номер VII», сопоставитель /V?I{0,3}/ возвращает «V», а не «VII», как хотелось бы.

Очевидно, что если мы используем шаблон /VI+/, тогда мы ДЕЙСТВИТЕЛЬНО получаем совпадение "VII" ... но это решение недействительно, если строка является чем-то вроде "Книги номер V", поскольку мы не получим совпадений ...

Я пытался добиться максимального захвата символов с помощью жадного квантификатора /VI{0,3}+/ или даже /VI*+/, но я все еще получаю совпадение "V" над "VII"

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 19 октября 2010

Я нашел, в чем была моя ошибка. Дело в том, что шаблоны типа /V?I{0,3}/ или /V?I*/ встречаются даже пустыми строками ... поэтому для строки типа "Книга VII" сопоставитель выдаст следующие совпадения результатов:

Result[0] --> ''
Result[1] --> '' 
Result[2] --> ''
Result[3] --> '' 
Result[4] --> '' 
Result[5] --> 'VII'
Result[6] --> '' 

Жадный результат есть (Результат [5]) в порядке. Моя проблема заключалась в том, что я всегда выбирал первое совпадение (Результат [0]), и это верно только в том случае, если шаблон не встречается пустыми строками.

Например, предлагаемый шаблон /V?I{1,3}|V/ выдаст только один результат, поэтому выбор первого результата совпадения - Ok:

Result[0] --> 'VII'

... Это так, поскольку шаблон не встречается пустыми строками.

Надеюсь, это поможет другим

0 голосов
/ 18 октября 2010

Почему не просто (IX | IV | V? I {1,3} | V)?

...