Извлекайте только ВСЕ слова CAPS в регулярном выражении RE2

Ищете способ извлечь из текстовой строки только слова, которые находятся в ALL CAPS. Подвох в том, что он не должен извлекать другие слова в текстовой строке, которые имеют смешанный регистр

Например, как я могу использовать регулярное выражение для извлечения KENTUCKY из следующего предложения:

Есть много вариантов в Кентукки

Я пытаюсь сделать это с помощью regexextract() в Google Sheets, который использует RE2.

Будем рады услышать ваши мысли.

Спасибо! Бен

4 ответа

Решение

Притворяться, что ваш текст находится в ячейке A2:

Если в каждом текстовом сегменте есть только один экземпляр, это будет работать:

=REGEXEXTRACT(A2,"([A-Z]{2,})")

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

=REGEXEXTRACT(A2, REPT(".* ([A-Z]{2,})", COUNTA(SPLIT(REGEXREPLACE(A2,"([A-Z]{2,})","$"),"$"))-1))

Если вам нужно извлечь целые куски слов в ALLCAPS, используйте

=REGEXEXTRACT(A2,"\b[A-Z]+(?:\s+[A-Z]+)*\b")
=REGEXEXTRACT(A2,"\b\p{Lu}+(?:\s+\p{Lu}+)*\b")

См. Эту демонстрацию регулярного выражения.

Детали

  • \b - граница слова
  • [A-Z]+ - 1+ букв ASCII (\p{Lu} соответствует любым буквам Unicode, включая арабский и т. д.)
  • (?:\s+[A-Z]+)* - ноль или более повторений
    • \s+ - 1+ пробелов
    • [A-Z]+ - 1+ букв ASCII (\p{Lu} соответствует любым буквам Unicode, включая арабский и т. д.)
  • \b - граница слова.

Или, если вы разрешаете любые знаки препинания или символы между прописными буквами, вы можете использовать

=REGEXEXTRACT(A2,"\b[A-Z]+(?:[^a-zA-Z0-9]+[A-Z]+)*\b")
=REGEXEXTRACT(A2,"\b\p{Lu}+(?:[^\p{L}\p{N}]+\p{Lu}+)*\b")

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

Вот, [^a-zA-Z0-9]+ соответствует одному или нескольким символам, отличным от букв и цифр ASCII, и [^\p{L}\p{N}]+ соответствует любому одному или нескольким символам, кроме букв и цифр Unicode.

Это должно работать:

\b[A-Z]+\b

Посмотреть демо

2-е решение EDIT ALL CAPS / UPPERCASE:

Наконец-то получил этот более простой способ из других замечательных вспомогательных решений здесь и здесь :

      =trim(regexreplace(regexreplace(C15,"(?:([A-Z]{2,}))|.", " $1"), "(\s)([A-Z])","$1 $2"))

Из этого ввода:

      isn'ter JOHN isn'tar DOE isn'ta or JANE

Он возвращает этот вывод:

      JOHN DOE JANE

То же самое для регистра заголовков (извлечение всех заглавных букв / с 1-й буквой в качестве прописных слов:

Формула:

      =trim(regexreplace(regexreplace(C1,"(?:([A-Z]([a-z]){1,}))|.", " $1"), "(\s)([A-Z])","$1 $2"))

Вход вC1:

      The friendly Quick Brown Fox from the woods Jumps Over the Lazy Dog from the farm.

Выход вA1:

      The Quick Brown Fox Jumps Over Lazy Dog

Предыдущие менее эффективные испытания:

Мне пришлось настроить его таким образом для моего варианта использования:

      = ArrayFormula(IF(REGEXMATCH(REGEXREPLACE(N3: N,
    "(^[A-Z]).+(,).+(\s[a-z]\s)|(^[A-Z][a-z]).+(\s[a-z][a-z]\s)|(^[A-Z]\s).+(\.\s[A-Z][a-z][a-z]\s)|[A-Z][a-z].+[0-9]|[A-Z][a-z].+[0-9]+|(^[A-Z]).+(\s[A-Z]$)|(^[A-Z]).+(\s[A-Z][a-z]).+(\s[A-Z])|(\s[A-Z][a-z]).+(\s[A-Z]\s).+(\s[A-Z])|(^[A-Z][a-z]).+(\s[A-Z]$)|(\s[A-Z]\s).+(\s[A-Z]\s)|(\s[A-Z]\s)|^[A-Z].+\s[A-Z]((\?)|(\!)|(\.)|(\.\.\.))|^[A-Z]'|^[A-Z]\s|\s[A-Z]'|[A-Z][a-z]|[a-z]{1,}|(^.+\s[A-Z]$)|(\.)|(-)|(--)|(\?)|(\!)|(,)|(\.\.\.)|(\()|(\))|(\')|("
    ")|(“)|(”)|(«)|(»)|(‘)|(’)|(<)|(>)|(\{)|(\})|(\[)|(\])|(;)|(:)|(@)|(#)|(\*)|(¦)|(\+)|(%)|(¬)|(&)|(|)|(¢)|($)|(£)|(`)|(^)|(€)|[0-9]|[0-9]+",
    ""), "[A-Z]{2,}") = FALSE, "", REGEXREPLACE(N3: N,
    "(^[A-Z]).+(,).+(\s[a-z]\s)|(^[A-Z][a-z]).+(\s[a-z][a-z]\s)|(^[A-Z]\s).+(\.\s[A-Z][a-z][a-z]\s)|[A-Z][a-z].+[0-9]|[A-Z][a-z].+[0-9]+|(^[A-Z]).+(\s[A-Z]$)|(^[A-Z]).+(\s[A-Z][a-z]).+(\s[A-Z])|(\s[A-Z][a-z]).+(\s[A-Z]\s).+(\s[A-Z])|(^[A-Z][a-z]).+(\s[A-Z]$)|(\s[A-Z]\s).+(\s[A-Z]\s)|(\s[A-Z]\s)|^[A-Z].+\s[A-Z]((\?)|(\!)|(\.)|(\.\.\.))|^[A-Z]'|^[A-Z]\s|\s[A-Z]'|[A-Z][a-z]|[a-z]{1,}|(^.+\s[A-Z]$)|(\.)|(-)|(--)|(\?)|(\!)|(,)|(\.\.\.)|(\()|(\))|(\')|("
    ")|(“)|(”)|(«)|(»)|(‘)|(’)|(<)|(>)|(\{)|(\})|(\[)|(\])|(;)|(:)|(@)|(#)|(\*)|(¦)|(\+)|(%)|(¬)|(&)|(|)|(¢)|($)|(£)|(`)|(^)|(€)|[0-9]|[0-9]+",
    "")))

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

@Wiktor Stribiżew любые предложения по упрощению будут очень кстати.

Нашли недостающие и исправили.

1-е РЕДАКТИРОВАТЬ :

Более простая версия, хотя и довольно длинная:

      = ArrayFormula(IF(REGEXMATCH(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(
            REGEXREPLACE(REGEXREPLACE(P3: P, "[a-z,]",
                " "), "-|\.", " "), "(^[A-Z]\s)", " "
            ), "(\s[A-Z]\s)", " "),
    "\sI'|\sI\s|^I'|^I\s|\sI(\.|\?|\!)|\sI$|\sA\s|^A\s|\.\.\.|\.|-|--|,|\?|\!|\.|\(|\)|'|"
    "|:|;|\'|“|”|«|»|‘|’|<|>|\{|\}|\[|\]|@|#|\*|¦|\+|%|¬|&|\||¢|$|£|`|^|€|[0-9]|[0-9]+",
    " "), "[A-Z]{2,}") = FALSE, " ", REGEXREPLACE(
    REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(
            P3: P, "[a-z,]", " "), "-|\.", " "),
        "(^[A-Z]\s)", " "), "(\s[A-Z]\s)", " "),
    "\sI'|\sI\s|^I'|^I\s|\sI(\.|\?|\!)|\sI$|\sA\s|^A\s|\.\.\.|\.|-|--|,|\?|\!|\.|\(|\)|'|"
    "|:|;|\'|“|”|«|»|‘|’|<|>|\{|\}|\[|\]|@|#|\*|¦|\+|%|¬|&|\||¢|$|£|`|^|€|[0-9]|[0-9]+",
    " ")))

Из этого примера:

Несколько совпадений регулярных выражений в формуле Google Sheets

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