#regex
#регулярное выражение
Вопрос:
Я хотел бы точно сопоставить строки типа «10a3b4c», «10a», «5b4c», «3a6c», но не «2c1b» (потому что буквы расположены не в алфавитном порядке) или пустую строку.
Попытка: (d a)?(d b)?(d c)?
Проблема: соответствует пустой строке. Оно ошибочно соответствует «».
Попытка: (d [abc]){1,3}
Проблема: не обеспечивает соблюдение a
, b
c
порядка. Оно ошибочно соответствует «2c1b»
Как это ограничение может быть выражено в виде регулярного выражения?
Комментарии:
1. Пожалуйста, объясните, что делает строку подходящей, а что нет. Например, почему должно
4a6c
совпадать, но2c1b
не должно? Что является рациональным?2. @EnricoMariaDeAngelis, потому что
2c1b
это не вa
,b
порядкеc
3. Вы привели пример из 4 строк, которые вы хотите сопоставить, и 1 строки, которую вы не хотите сопоставлять, но вы никогда не объясняли, что первые четыре строки имеют в commond, чего нет в пятой строке.
4. @EnricoMariaDeAngelis их объединяет то, что они являются «по крайней мере одной из [этих групп]
d a
,d b
d c
и в таком порядке», однако пятая строка находится не в таком порядке5. Используйте
^(?!$)(d a)?(d b)?(d c)?$
Ответ №1:
Используйте
^(?!$)(d a)?(d b)?(d c)?$
Смотрите доказательство
Объяснение
EXPLANATION
--------------------------------------------------------------------------------
^ the beginning of the string
--------------------------------------------------------------------------------
(?! look ahead to see if there is not:
--------------------------------------------------------------------------------
$ before an optional n, and the end of
the string
--------------------------------------------------------------------------------
) end of look-ahead
--------------------------------------------------------------------------------
( group and capture to 1 (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
d digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
a 'a'
--------------------------------------------------------------------------------
)? end of 1 (NOTE: because you are using a
quantifier on this capture, only the LAST
repetition of the captured pattern will be
stored in 1)
--------------------------------------------------------------------------------
( group and capture to 2 (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
d digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
b 'b'
--------------------------------------------------------------------------------
)? end of 2 (NOTE: because you are using a
quantifier on this capture, only the LAST
repetition of the captured pattern will be
stored in 2)
--------------------------------------------------------------------------------
( group and capture to 3 (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
d digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
c 'c'
--------------------------------------------------------------------------------
)? end of 3 (NOTE: because you are using a
quantifier on this capture, only the LAST
repetition of the captured pattern will be
stored in 3)
--------------------------------------------------------------------------------
$ before an optional n, and the end of the
string
Комментарии:
1. Это работает, только если строки по одной в каждой строке.
2. @EnricoMariaDeAngelis Это точный ввод, который имеет OP.
3. в OP ничего не говорится о том, находятся строки в одной строке каждая или нет. Насколько я знаю, нет флага, который делает
^
и$
совпадающими границы слов.4. @theonlygusti, регулярное выражение в этом ответе не может совпадать, если слова находятся в одной строке.
5. @EnricoMariaDeAngelis оно соответствует по одному на строку, потому что в ссылке regex101 Ryszard включен флаг многострочности.
Ответ №2:
Кажется, это работает (см. Это в regex101)
b(?=[dabc] b)(d a)?(d b)?(d c)?b
Комментарии:
1. Это не эквивалентно. Проверьте регулярное выражение 101.
2. @theonlygusti,
b
это не причина, почему(?=[dabc] b)
и(?=.)
имеют два разных эффекта.