Соответствие пустому пространству после последнего символа не является универсальным.
Редактор Vim имеет такое поведение:
Буфер до:
aaaa
~
~
:s/x\?/y/g <- command
Буфер после:
yayaya
~
~
Нет x
происходит в aaaa
, но x?
(по умолчанию записывается x\?
в Vim) допускает пустое совпадение. Шаблон соответствует пустому пространству в начале строки и между
все персонажи, но не до конца.
Исключением является пустая строка. Команда заменит пустую строку одной y
.
Я реализовал поведение, подобное Vim, в моей собственной программе:
$ txr -c '@(bind result @(regsub #/x?/ "y" "aaaa"))'
result="yayayaya"
$ txr -c '@(bind result @(regsub #/x?/ "y" ""))'
result="y"
Только потому, что Vim популярен, и я могу указать на это в качестве эталонной модели, если возникнут какие-либо вопросы. Но это немного взломать. Логика имеет цикл do .. while
, который позволяет обрабатывать входящую пустую строку:
do {
/* regex match, extraction, substitution ... */
position++;
} while (position < length(input))
Таким образом, если начальная позиция равна нулю, а вход имеет нулевую длину, мы делаем цикл один раз, применяя регулярное выражение к пустой строке. Но если мы обработаем последний символ, позиция достигает длины, и цикл завершается без обработки пустой строки.
Изначально у меня был циклический тест сверху, поэтому он вел себя как Vim, но не в пустом регистре ввода, который не соответствовал бы регулярным выражениям, которые совпадают в пустом.
Поведение используемого вами Java-класса может быть реализовано так:
while (position <= length(input)) {
/* process regex */
position++;
}