Регулярное выражение: найти последнюю уникальную подстроку в конце строки

Соответствовать

condition #1.The last occurrence of a string of characters followed by a comma or white space.
condition #2.The occurrence has to be the end of the string
condition #3.The occurrence has to be a unique sub-string

Я не могу понять, как применить третье условие к моему регулярному выражению.

Выражение:

/[\w]{2,30}[\s,](?!.*[\w]{2,30}[\s,])$/g

[\w]{2,30}                    --Any sub-string of characters of length 2 to 30
[\s,]                         --Is white space or comma
(?!.*[\w]{2,30}[\s,])         --Only match the last occurrence
$                             --End of string

Мое выражение охватывает только условия №1 и №2.

#1. The last occurrence of a string of characters followed by a comma or white space.
#2. The occurrence has to be the end of the string.

Я хочу, чтобы мое выражение возвращало совпадение, когда [\w]{2,30} является уникальным И #1 #2 все еще действительны.

//Result
string: 'a, bb, ccc, ccc(space or ,)'
match: 'ccc(space or ,)'

//Expected Results
string: 'a, bb, ccc, ccc(space or ,)'
match: no match

string: 'a, bb, ccc, ccc(space), abc(space or ,)'
match: 'abc(space or ,)'

string: 'a, bb, ccc, ccc(space), abc(space or ,)(any character or white space or ,)'
match: no match
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел "Заголовок" в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
Как React Helmet спасает меня при разделении файлов CSS?
Как React Helmet спасает меня при разделении файлов CSS?
Многие новички могут столкнуться с проблемой, когда одна страница с CSS наследует свойства от другой страницы с другим CSS. У меня было много проблем,...
3
0
61
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

/(?<=\s|^)[\w]{2,30}\s,/g

Давайте разберем это:

(?<=\s|^) — Положительный просмотр назад, чтобы гарантировать, что совпадению предшествует пробел или начало строки.

[\w]{2,30} — любая подстрока символов длиной от 2 до 30.

[\s,] - пробел или запятая.

(?=(?:(?!\1)[\w]{2,30}[\s,])*[\w]{2,30}[\s,]$) - Положительный просмотр вперед, чтобы гарантировать, что подстрока не повторяется ранее в строке и является последним вхождением.

Это достигается с помощью незахватывающей группы (?:) с отрицательным опережением для проверки любого предыдущего вхождения той же подстроки, за которой следует та же подстрока в конце строки.

Обратите внимание, что использование \1 в отрицательном прогнозе относится к предыдущей захваченной группе, которая в данном случае является подстрокой символов, соответствующей предыдущему экземпляру [\w]{2,30}[\s,].

\1 возвращает ошибку. Вот ссылка regex101.com/r/3K0bkq/1

Justin Coleman 17.02.2023 07:06

(?<=\s|^)[\w]{2,30}[\s,] возвращает несколько совпадений. regex101.com/r/F2B4TP/1. Должно быть только одно совпадение, и оно должно быть в конце строки.

Justin Coleman 17.02.2023 07:09

Вы можете попробовать:

\b(\w{2,30})(?<!\b\1\b.*?\b\1\b)[ ,]$

Посмотреть онлайн демо


  • \b(\w{2,30}) - граница слова, за которой следует группа захвата, соответствующая подстроке из 2-30 символов слова;
  • (?<!\b\1\b.*?\b\1\b) - Отрицательный просмотр назад (допускается нулевая ширина) для проверки ранее захваченной подстроки, которая ранее не была найдена;
  • [ ,]$ - Пробел или запятая перед якорем конечной строки.

const r1 = ['a, bb, ccc, ccc ', 'a, bb, ccc, ccc , abc ', 'a, bb, ccc, ccc , abc  '];
const r2 = r1.map(Re_Extract);

function Re_Extract(str) {
  const s = str.match(/\b(\w{2,30})(?<!\b\1\b.*?\b\1\b)[ ,]$/g);
  if (s) {
    return s[0];
  }
  else {
    return s;
  }
}

console.info(r2);
Ответ принят как подходящий

В своем шаблоне вы только сопоставляете, но не проверяете одно и то же вхождение шаблона \w{2,30}, чтобы убедиться, что он уникален.

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

^(?!.*\b(\w{2,30})\b.*\1[,\s]$).*\b(\w{2,30}[,\s])$

Объяснение

  • ^ Начало строки
  • (?! Отрицательный просмотр вперед, утверждение, что вправо не
    • .*\b(\w{2,30})\b Сопоставьте всю строку, затем границу слова и захватите в группе 1 соответствие от 2 до 30 символов слова, за которыми следует граница слова.
    • .*\1 Сопоставьте всю строку, а затем обратную ссылку на группу захвата 1, чтобы сопоставить тот же текст.
    • [,\s]$ Соответствует либо ,, либо пробелу в конце строки
  • ) Закрыть просмотр вперед
  • .* Соответствуйте всей линии
  • \b(\w{2,30}[,\s]) Граница слова, сопоставьте от 2 до 30 символов слова, за которыми следует либо ,, либо символ пробела.
  • $ Конец строки

Посмотрите демоверсию regex101

const regex = /^(?!.*\b(\w{2,30})\b.*\1[,\s]$).*\b(\w{2,30}[,\s])$/;
[
  "a, bb, ccc, ccc ",
  "a, bb, ccc, ccc , abc ",
  "a, bb, ccc, ccc , abc  "
].forEach(s => {
  console.info(`${regex.test(s)} ---> ${s}`);
})

Тай! Я считаю, что ваш ответ является наиболее полным, потому что он решил задачу, и вы дали более полное объяснение компонентов в своем выражении.

Justin Coleman 17.02.2023 18:20

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