Извлекайте только ВСЕ слова 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.
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