R Language
Регулярные выражения (регулярное выражение)
Поиск…
Вступление
Регулярные выражения (также называемые «регулярное выражение» или «регулярное выражение») определяют шаблоны, которые можно сопоставить с строкой . Введите ?regex
для официальной документации R и просмотрите Документы Regex для более подробной информации. Наиболее важная «gotcha», которая не будет изучена в SO regex / themes, заключается в том, что большинству функций R-regex требуется использование спаренных обратных косых черт для выхода из параметра pattern
.
замечания
Классы символов
-
"[AB]"
может быть A или B -
"[[:alpha:]]"
может быть любая буква -
"[[:lower:]]"
означает любую строчную букву. Обратите внимание, что"[az]"
близко, но не соответствует, например,ú
. -
"[[:upper:]]"
означает любую прописную букву. Обратите внимание, что"[AZ]"
близко, но не соответствует, например,Ú
. -
"[[:digit:]]"
обозначает любую цифру: 0, 1, 2, ... или 9 и эквивалентна"[0-9]"
.
Кванторы
+
, *
и ?
как обычно, в регулярном выражении. - +
совпадает хотя бы один раз, *
соответствует 0 или более раз, и ?
соответствует 0 или 1 раз.
Индикаторы начала и конца строки
Вы можете указать положение регулярного выражения в строке:
-
"^..."
заставляет регулярное выражение находиться в начале строки -
"...$"
заставляет регулярное выражение находиться в конце строки
Различия с другими языками
Обратите внимание, что регулярные выражения в R часто выглядят так или иначе отличными от регулярных выражений, используемых на других языках.
R требует двойных обратных следов (потому что
"\"
уже подразумевает экранирование вообще в R-строках), поэтому, например, для захвата пробелов в большинстве движков регулярных выражений просто нужно ввести\s
, vs.\\s
в R ,Символы UTF-8 в R должны быть экранированы с капиталом U, например,
[\U{1F600}]
и[\U1F600]
совпадением 😀, тогда как, например, в Ruby, это будет соответствовать нижнему регистру u.
Дополнительные ресурсы
Следующий сайт reg101 - хорошее место для проверки онлайн-регулярного выражения перед использованием R-скрипта.
В программе программирования Wikibook есть страница, посвященная обработке текста, с множеством примеров с использованием регулярных выражений.
Устранение пробелов
string <- ' some text on line one;
and then some text on line two '
Обрезка пропусков
Пробел «Обрезка» обычно относится к удалению как ведущего, так и конечного пробела из строки. Это можно сделать, используя комбинацию из предыдущих примеров. gsub
используется для принудительной замены как ведущих, так и конечных совпадений.
До R 3.2.0
gsub(pattern = "(^ +| +$)",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two"
R 3.2.0 и выше
trimws(x = string)
[1] "some text on line one; \nand then some text on line two"
Удаление ведущих пробелов
До R 3.2.0
sub(pattern = "^ +",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two "
R 3.2.0 и выше
trimws(x = string,
which = "left")
[1] "some text on line one; \nand then some text on line two "
Удаление пропущенных пробелов
До R 3.2.0
sub(pattern = " +$",
replacement = "",
x = string)
[1] " some text on line one; \nand then some text on line two"
R 3.2.0 и выше
trimws(x = string,
which = "right")
[1] " some text on line one; \nand then some text on line two"
Удаление всех пробелов
gsub(pattern = "\\s",
replacement = "",
x = string)
[1] "sometextonlineone;andthensometextonlinetwo"
Обратите внимание, что это также удалит символы пробела, такие как вкладки ( \t
), новые строки ( \r
и \n
) и пробелы.
Проверка даты в формате «YYYYMMDD»
Общепринятой практикой является имя файлов с использованием даты в качестве префикса в следующем формате: YYYYMMDD
, например: 20170101_results.csv
. Дата в таком строчном формате может быть проверена с использованием следующего регулярного выражения:
\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])
Вышеприведенное выражение рассматривает даты года: 0000-9999
, месяцев между: 01-12
и днями 01-31
.
Например:
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170101")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20171206")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "29991231")
[1] TRUE
Примечание . Он проверяет синтаксис даты, но мы можем иметь неправильную дату с допустимым синтаксисом, например: 20170229
(2017 год - это не високосный год).
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170229")
[1] TRUE
Если вы хотите проверить дату, это можно сделать с помощью этой функции, определенной пользователем:
is.Date <- function(x) {return(!is.na(as.Date(as.character(x), format = '%Y%m%d')))}
затем
> is.Date(c("20170229", "20170101", 20170101))
[1] FALSE TRUE TRUE
Подтверждение почтовых абзацев США
Следующее regex
включает 50 штатов, а также Commonwealth / Territory (см. Www.50states.com ):
regex <- "(A[LKSZR])|(C[AOT])|(D[EC])|(F[ML])|(G[AU])|(HI)|(I[DLNA])|(K[SY])|(LA)|(M[EHDAINSOT])|(N[EVHJMYCD])|(MP)|(O[HKR])|(P[WAR])|(RI)|(S[CD])|(T[NX])|(UT)|(V[TIA])|(W[AVIY])"
Например:
> test <- c("AL", "AZ", "AR", "AJ", "AS", "DC", "FM", "GU","PW", "FL", "AJ", "AP")
> grepl(us.states.pattern, test)
[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
>
Примечание .
Если вы хотите проверить только 50 государств, то мы рекомендуем использовать R- state.abb
: state.abb
из state
, например:
> data(state)
> test %in% state.abb
[1] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
Мы получаем TRUE
только для сокращений 50 государств: AL, AZ, AR, FL
.
Подтвердите номера телефонов США
Следующее регулярное выражение:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
Проверяет номер телефона в виде: +1-xxx-xxx-xxxx
, включая необязательные ведущие / завершающие пробелы в начале / конце каждой группы чисел, но не посередине, например: +1-xxx-xxx-xx xx
недействителен. -
разделитель можно заменить пробелами: xxx xxx xxx
или без разделителей: xxxxxxxxxx
. Префикс +1
является обязательным.
Давайте проверим:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
phones.OK <- c("305-123-4567", "305 123 4567", "+1-786-123-4567",
"+1 786 123 4567", "7861234567", "786 - 123 4567", "+ 1 786 - 123 4567")
phones.NOK <- c("124-456-78901", "124-456-789", "124-456-78 90",
"124-45 6-7890", "12 4-456-7890")
Действующие случаи:
> grepl(us.phones.regex, phones.OK)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
>
Недействительные случаи:
> grepl(us.phones.regex, phones.NOK)
[1] FALSE FALSE FALSE FALSE FALSE
>
Примечание .
-
\\s
Соответствует любому символу пробела, табуляции или символа новой строки
Экранирование символов в шаблонах регулярных выражений R
Поскольку и R, и регулярное выражение разделяют escape-символ, "\"
, создание правильных шаблонов для grep
, sub
, gsub
или любой другой функции, принимающей аргумент шаблона, часто требует спаривания обратных косых черт. Если вы создаете вектор символа из трех элементов, в котором у одного элемента есть строка, другой символ табуляции и ни один, ни один из них, и hte желание состоит в том, чтобы повернуть либо перевод строки, либо вкладку в 4 пробела, тогда нужна одна обратная косая черта для построения, но смятые обратные косые черты для соответствия:
x <- c( "a\nb", "c\td", "e f")
x # how it's stored
# [1] "a\nb" "c\td" "e f"
cat(x) # how it will be seen with cat
#a
#b c d e f
gsub(patt="\\n|\\t", repl=" ", x)
#[1] "a b" "c d" "e f"
Обратите внимание, что аргумент шаблона (который является необязательным, если он появляется первым и требует только частичного написания), является единственным аргументом, требующим этого удвоения или спаривания. Аргумент замены не требует удвоения символов, которые необходимо экранировать. Если вы хотите, чтобы все строки и 4-пространственные вхождения заменялись вкладками, это было бы:
gsub("\\n| ", "\t", x)
#[1] "a\tb" "c\td" "e\tf"
Различия между Perl и POSIX regex
В R есть два очень-очень разных двигателя регулярных выражений. Значение по умолчанию называется POSIX-согласованным; все функции регулярных выражений в R также оснащены возможностью включить последний тип: perl = TRUE
.
Смотри вперед / смотреть-за
perl = TRUE
позволяет смотреть вперед и смотреть в регулярных выражениях.
-
"(?<=A)B"
соответствует появлению буквыB
только в том случае, если ей предшествуетA
, то есть"ABACADABRA"
будет соответствовать, но"abacadabra"
и"aBacadabra"
не будут.