Регулярные выражения javascript - группы

В настоящее время я изучаю группы регулярных выражений. Мне трудно полностью понять первый пример, представленный в книге в разделе групп. В книге приведен следующий пример:

/(\S+) (\S*) ?\b(\S+)/

Я понимаю, что это будет соответствовать не более чем трем словам (состоящим из любого символа, кроме пробела), где второе слово и пробел не являются обязательными.

Что мне трудно понять, так это функцию граничного условия, чтобы начать совпадение последней группы в начале третьего слова.

Когда есть три слова, не имеет значения, включено оно или нет.

Регулярные выражения javascript - группыРегулярные выражения javascript - группы

Когда есть только два слова, есть разница между группой № 2 и группой № 3.

Регулярные выражения javascript - группыРегулярные выражения javascript - группы

Итак, мой вопрос заключается в следующем

Когда есть два слова, почему присутствие \b приводит к тому, что группа №2 является пустой строкой, как и ожидалось, но когда оно отсутствует, приводит к тому, что группа №2 содержит второе слово минус последняя буква, а группа №3 содержит последнюю букву второго слова?

См. stackoverflow.com/questions/2301285/…

gman 03.06.2019 06:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
1
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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+) может быть удовлетворен, заключается в следующем:

  • матчи группы 1 the
  • символ пробела соответствует
  • группа 2 ничему не соответствует, что допустимо, так как она может соответствовать любой сумме, включая ноль
  • необязательный пробел соответствует нулю пробелов
  • есть граница слова
  • группа 3 потребляет остальные буквы - brown

Другие вопросы по теме