Когда есть два слова, почему присутствие \ b приводит к тому, что группа # 2 становится пустой строкой, как и ожидалось
Посмотрите на первую и третью группы - будучи (\S+)
, они должны содержать символы. Когда есть два слова, эти два слова должны входить в первую и третью группы - во вторую группу, поскольку она повторяется с *
, не будет потреблять никаких символов и будет пустой строкой.
но когда отсутствует, группа № 2 содержит второе слово минус последняя буква, а группа № 3 содержит последнюю букву второго слова?
Когда шаблон
(\S+) (\S*) ?(\S+)
как только двигатель соответствует первому слову, двигатель начнет пытаться сопоставить второе слово. Таким образом, если ввод foo bar
, мы можем рассмотреть, как шаблон (\S*) ?(\S+)
работает на bar
.
Движок сначала пытается использовать все оставшиеся символы в строке с \S*
. Это терпит неудачу, потому что последняя группа должна содержать хотя бы один символ, поэтому движок выполняет резервное копирование шага, и группа \S*
соответствует всем, кроме последнего символа. Это приводит к успешному совпадению, потому что позиция перед последним символом соответствует \s?(\S+)
.
Вы можете увидеть этот процесс визуально здесь:
https://regex101.com/r/RAkEOt/1/debugger
![enter image description here](https://i.stack.imgur.com/LflFu.png)
В первом шаблоне граница слова перед последней группой гарантирует, что вторая группа не соответствует никаким символам, если в строке только два слова - вместо возврата к непосредственно перед последним символ, он должен полностью выполнять резервное копирование, пока не будет найдена граница слова:
![enter image description here](https://i.stack.imgur.com/kRgOs.png)
Исходный шаблон может быть слегка ошибочным - \b
соответствует границе слова , но не каждый непробельный символ является символом слова - он (вероятно, нежелательно) соответствует foo it's
, где it'
переходит во вторую группу, а s
переходит в третью группу.