Как я могу сделать так, чтобы это соответствовало только словам после слова «говорит» и игнорировало запятые и пробелы

#regex

#регулярное выражение

Вопрос:

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

 /(?<=wsspeakss)(?!,|s|.)([w] )/gmi
 

Строка:

 Example Person speaks ExampleLanguage1, ExampleLanguage2, ExampleLanguage3 and ExampleLanguage4.
Example Person two speaks ExampleLanguage1, ExampleLanguage2, ExampleLanguage3 and ExampleLanguage4.
Example Person three speaks ExampleLanguage1 and ExampleLanguage2.
 

Для меня приведенное выше соответствует только:

 ExampleLanguage1
ExampleLanguage1
ExampleLanguage1
 

Я хочу сопоставить:

 ExampleLanguage1
ExampleLanguage2
ExampleLanguage3
ExampleLanguage4
ExampleLanguage1
ExampleLanguage2
ExampleLanguage3
ExampleLanguage4
ExampleLanguage1
ExampleLanguage2
 

Примером слова Person может быть любое слово, даже без пробела между ними.
И в словах ExampleLanguage не отмечены цифры. И они также могут содержать пробелы и могут быть любым словом.

Вот ссылка на него: https://regex101.com/r/MjL8cW/1

Ответ №1:

Если вы можете использовать G привязку, вы можете сопоставить 4 или более символов word или сопоставить слова с 1-3 символами и использовать K для очистки буфера соответствия.

 (?:^.*?hspeaks|w{1,3}|G(?!^))[,.]?h Kw{4,}
 

Шаблон соответствует:

  • (?: Не группа захвата
    • ^.*?hspeaks Сопоставление от начала строки до первого появления символа пробела и говорит.
    • | Или
    • w{1,3} Сопоставьте символы 1-3 слов
    • | Или
    • G(?!^) Подтвердите позицию в конце предыдущего совпадения, но не в начале
  • ) Закрыть группу без захвата
  • [,.]?h Сопоставьте необязательный , или . и 1 или более горизонтальных символов пробела
  • Kw{4,} Забудьте, что соответствует до сих пор, используя K и сопоставляя 4 или более символов word

Демонстрация регулярных выражений

Комментарии:

1. Но я хочу только сопоставить их. Я не хочу использовать группы! Я знаю, что это сложно, но я уверен, что это возможно.

2.@Chi.C.J.RajeevaLochana Вот так? (?:^.*?sspeaks|w{1,3}|G(?!^))[,.]?h*Kw{4,} regex101.com/r/f6oYA4/1

3. Да, это именно то, что я хочу.

4. «Игнорировать запятые и пробелы» можете ли вы создать временное String , заменить запятые и пробелы пустой строкой ( String temp = origStr.replace(",", "").replace(" ", "") ) и оценить ваше регулярное temp выражение? Я бы подумал, что это должно упростить ваше регулярное выражение.

Ответ №2:

Используйте

 (?<=bspeaksb.*?)bw{4,}b
 

Смотрите Доказательство.

Объяснение

 --------------------------------------------------------------------------------
  (?<=                     look behind to see if there is:
--------------------------------------------------------------------------------
    b                       the boundary between a word char (w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    speaks                   'speaks'
--------------------------------------------------------------------------------
    b                       the boundary between a word char (w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    .*?                      any character except n (0 or more times
                             (matching the least amount possible))
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  b                       the boundary between a word char (w) and
                           something that is not a word char
--------------------------------------------------------------------------------
  w{4,}                   word characters (a-z, A-Z, 0-9, _) (at
                           least 4 times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  b                       the boundary between a word char (w) and
                           something that is not a word char
 

ДЕМОНСТРАЦИЯ

 const string = `Example Person speaks ExampleLanguage1, ExampleLanguage2, ExampleLanguage3 and ExampleLanguage4.
Example Person two speaks ExampleLanguage1, ExampleLanguage2, ExampleLanguage3 and ExampleLanguage4.
Example Person three speaks ExampleLanguage1 and ExampleLanguage2.`
console.log(string.match(/(?<=bspeaksb.*?)bw{4,}b/gi)) 

Ответ №3:

Оператор continue кажется здесь правильным. Принятое в порядке, но есть проблема с 3-буквенными языками, такими как Яо, Мин, Мон (говорят в Африке, Азии …)

Попробуйте что-нибудь в этом роде:

 (?i)(?:speakss*K|(?<!^)G(?:,|,?s*and)s*K)(?-i)([A-Z](?i)w )
 

ДЕМОНСТРАЦИЯ

Комментарии:

1. @Chi.C.J.RajeevaLochana ну, все еще может быть проблемой полагаться на длину языка. Просто говорю; тем не менее, другое решение тоже хорошо.

2. @Chi.C.J.RajeevaLochana regex101.com/r/EetTRw/2

3. не сосредоточился на этом .. упс