В настоящее время я изучаю группы регулярных выражений. Мне трудно полностью понять первый пример, представленный в книге в разделе групп. В книге приведен следующий пример:
/(\S+) (\S*) ?\b(\S+)/
Я понимаю, что это будет соответствовать не более чем трем словам (состоящим из любого символа, кроме пробела), где второе слово и пробел не являются обязательными.
Что мне трудно понять, так это функцию граничного условия, чтобы начать совпадение последней группы в начале третьего слова.
Когда есть три слова, не имеет значения, включено оно или нет.
Когда есть только два слова, есть разница между группой № 2 и группой № 3.
Итак, мой вопрос заключается в следующем
Когда есть два слова, почему присутствие \b приводит к тому, что группа №2 является пустой строкой, как и ожидалось, но когда оно отсутствует, приводит к тому, что группа №2 содержит второе слово минус последняя буква, а группа №3 содержит последнюю букву второго слова?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


When there are two words, why is the presence of \b causing group#2 to be an empty string as expected
Посмотрите на первую и третью группы — это (\S+), они содержат символы должен. Когда есть два слова, эти два слова должны попасть в первую и третью группу - вторая группа, поскольку она повторяется с *, не будет потреблять никаких символов и будет пустой строкой.
but when not present causes group #2 to contain the second word minus the last letter and group #3 to contain the last letter of the second word?
Когда шаблон
(\S+) (\S*) ?(\S+)
как только движок сопоставит первое слово, движок начнет пытаться сопоставить второе слово. Итак, если на входе foo bar, мы можем рассмотреть, как шаблон (\S*) ?(\S+) работает на bar.
Сначала движок пытается использовать все оставшиеся символы в строке с помощью \S*. Это не удается, потому что последняя группа должна содержать хотя бы один символ, поэтому движок делает резервную копию шага, и группа \S* соответствует всем символам, кроме последнего. Это приводит к успешному совпадению, потому что позиция перед последним символом соответствует \s?(\S+).
Наглядно увидеть этот процесс можно здесь:
https://regex101.com/r/RAkEOt/1/отладчик
В первом шаблоне граница слова перед последней группой гарантирует, что вторая группа не соответствует никаким символам, в случае, если в строке только два слова — вместо возврата к символу незадолго до последнего, она должна выполнять резервное копирование до конца. граница слова найдена:
Исходный шаблон может быть немного ошибочным - \b соответствует граница слова, но не каждый символ, не являющийся пробелом, является символом слова - это (возможно, нежелательно) совпадения foo it's, где it' входит во вторую группу, а s входит в третью группу.
Отличие заключается во второй группе (\S*) — она будет захватывать любое количество непробельных символов. Итак, когда у вас есть два слова, но три группы, где последней является (\S+) - соответствует непробельному символу хотя бы один, механизм регулярных выражений попытается удовлетворить как группу 2, так и группу 3.
Помните, что он соответствует шаблону, и вы не указали ему нет, чтобы он соответствовал этому. Следовательно, он выполняет минимальную необходимую работу - вторая группа \S* изначально будет соответствовать всему захвату brown - следующая часть шаблона - это необязательный пробел, который проходит, затем он попадает в последнюю группу \S+ и, поскольку он имеет обязательный характер, второй матч будет выпускать матчи один за другим, пока группа 3 не будет удовлетворена.
Вы можете увидеть это здесь — я определил, что третья группа должна иметь как минимум два обязательных символа, поэтому она получает только два:
let [ , group1, group2, group3] = "the brown".match(/(\S+) (\S*) ?(\S{2,})/);
console.info("group 1:", group1)
console.info("group 2:", group2)
console.info("group 3:", group3)Когда вместо этого вы добавляете границу слова \b в шаблон, у вас не может быть группы 2, в которой какие-либо символы а также удовлетворяют более позднему условию - когда регулярное выражение использует символ, остальная часть шаблона будет продолжаться только с этого символа и далее, поэтому вы не можете иметь, например, группа 2 соответствует b, а затем имеет границу слова, за которой следует rown. Единственный способ, которым (\S+) (\S*) ?\b(\S+) может быть удовлетворен, заключается в следующем:
thebrown
См. stackoverflow.com/questions/2301285/…