Сопоставьте от одной до трех групп, только если они отображаются в порядке

#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) и (?=.) имеют два разных эффекта.