Как я могу исправить свое регулярное выражение, чтобы параметр 3 оставался в группе захвата 3? - PullRequest
2 голосов
/ 21 мая 2019

У меня есть следующее выражение регулярного выражения:

^(\d*)(?:\.)(\d*)(?:|(?:\.)(\d*))(?:|(?:\.)([a-zA-Z0-9_-]*))?$

Вы можете проверить это здесь .
Я хочу использовать его, например, для разбора номера версии на группы (где g1 - группа № 1 и т. д.):

1.2              =>  g1(1),g2(2)    
1.2.3            =>  g1(1),g2(2),g3(3)    
1.2.3.4_or_text  =>  g1(1),g2(2),g3(3),g4(4_or_text)  

Это почти работает, за исключением случаев, когда третья группа является необязательной, и переход к четвертой группе, если версия состоит из 3 частей.
Итакчто на самом деле происходит так:

1.2              =>  g1(1),g2(2)    
1.2.3            =>  g1(1),g2(2),g3(),g4(3)           <-- I want to fix this
1.2.3.4_or_text  =>  g1(1),g2(2),g3(3),g4(4_or_text) 

Я не могу точно определить, что я делаю неправильно.

То, как он работает сейчас, также означает, что справедливо следующее: 1.2.3_or_text, поскольку он анализируется как g1(1),g2(2),g3(),g4(3_or_text)

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

У вас есть дополнительное alternation(|) выражение в вашем регулярном выражении

^(\d*)(?:\.)(\d*)(?:|(?:\.)(\d*))(?:|(?:\.)([a-zA-Z0-9_-]*))?$
                    ^               ^
                   this            this

Указывает на совпадение ничего , которое всегда проходит. В результате ваша вторая часть чередования никогда не совпадает.

Дальнейшее объяснение : Синтаксис чередования похож на

(?:a|b|c)

В вашем случае a - это ничто, поэтому всегда верно и соответствует

Правильное решение : Вам также не хватает необязательной группы и предполагается, что должна быть хотя бы одна цифра или алфавит, это должно быть правильным регулярным выражением

^(\d+)(?:\.)(\d+)(?:(?:\.)(\d+))?(?:(?:\.)([a-zA-Z0-9_-]+))?$

Бит чистого раствора

^(\d+)[.](\d+)(?:[.](\d+)(?:[.]([\w-]+))?)?$

Распределение регулярных выражений

^ #Start of string
 (\d+)[.] #Match digit and dot
 (\d+) #Match next group

 (?: #Non-capturing group
   [.](\d+) #Match dot and digit
   (?:[.]([\w-]+))? #Match dot and digit. This is optional
 )? #Third and Fourth match can be optional

$ #End of string
2 голосов
/ 21 мая 2019

Вы можете использовать это регулярное выражение с 2 необязательными группами без захвата:

^(\d+)\.(\d+)(?:\.(\d+)(?:\.([\w-]+))?)?$

RegEx Demo

подробности:

  • ^ `: начало
  • (\d+): сопоставить и перехватить 1+ цифр в группе захвата # 1
  • \.: соответствует литералу .
  • (\d+): сопоставить и перехватить 1+ цифр в группе захвата # 2
  • (?: Начало группы без захвата # 1
    • \.: соответствует литералу .
    • (\d+): сопоставить и перехватить 1+ цифр в группе захвата # 3
    • (?:: начать группу без захвата # 2
      • \.: соответствует литералу .
      • ([\w-]+): сопоставить и перехватить 1+ слово или дефис в группе захвата # 4
    • )?: конец группы без захвата # 2 (необязательно)
  • )?: конец группы без захвата # 1 (необязательно)
  • $: конец
...