Вы должны быть в состоянии отладить написанное вами регулярное выражение.
> as.regex(pattern2)
<regex> ([\d]+)\.\s((?:[\w]+|[\w]+\s[\w]+))\s(\d\.[\d]+)
Подключите в regex101, и вы увидите, что ваши строки не всегда совпадают.Объяснение справа говорит вам, что вы можете разрешить только 1 или 2 пробела между точкой и числом.Кроме того, WRD
(шаблон [\w]+
) не соответствует точкам и любым другим символам, которые не являются буквами, цифрами или _
.Теперь вы знаете, что вам нужно сопоставить вашу строку с
^(\d+)\.(.*?)\s*(\d\.\d{2})$
См. это демонстрационное выражение regex .Перевод в Rebus:
pattern2 <- START %R% # ^ - start of string
capture(one_or_more(DGT)) %R% # (\d+) - Group 1: one or more digits
DOT %R% # \. - a dot
"(.*?)" %R% # (.*?) - Group 2: any 0+ chars as few as possible
zero_or_more(SPC) %R% # \s* - 0+ whitespaces
capture(DGT %R% DOT %R% repeated(DGT, 2)) %R% # (\d\.\d{2}) - Group 3: #.## number
END # $ - end of string
Проверка:
> pattern2
<regex> ^([\d]+)\.(.*?)[\s]*(\d\.[\d]{2})$
> companies <- c("612. Grt. Am. Mgt. & Inv. 7.33","77. Wickes 4.61","265. Wang Labs 8.75","9. CrossLand Savings 6.32","228. JPS Textile Group 2.00")
> str_match(companies, pattern = pattern2)
[,1] [,2] [,3] [,4]
[1,] "612. Grt. Am. Mgt. & Inv. 7.33" "612" " Grt. Am. Mgt. & Inv." "7.33"
[2,] "77. Wickes 4.61" "77" " Wickes" "4.61"
[3,] "265. Wang Labs 8.75" "265" " Wang Labs" "8.75"
[4,] "9. CrossLand Savings 6.32" "9" " CrossLand Savings" "6.32"
[5,] "228. JPS Textile Group 2.00" "228" " JPS Textile Group" "2.00"
ПРЕДУПРЕЖДЕНИЕ : capture(lazy(zero_or_more(ANY_CHAR)))
возвращает шаблон ([.]*?)
, который соответствует 0 или более точкам всего завозможно вместо сопоставления любых 0+ символов, потому что в rebus
есть ошибка: он охватывает все символы repeated
(one_or_more
или zero_or_more
) с [
и ]
, классом символов.Вот почему (.*?)
добавляется «вручную».
Это можно решить или обойти, используя общую конструкцию, такую как [\w\W]
/ [\s\S]
или [\d\D]
:
pattern2 <- START %R% # ^ - start of string
capture(one_or_more(DGT)) %R% # (\d+) - Group 1: one or more digits
DOT %R% # \. - a dot
capture( # Group 2 start:
lazy(zero_or_more(char_class(WRD, NOT_WRD))) # - [\w\W] - any 0+ chars as few as possible
) %R% # End of Group 2
zero_or_more(SPC) %R% # \s* - 0+ whitespaces
capture(DGT %R% DOT %R% repeated(DGT, 2)) %R% # (\d\.\d{2}) - Group 3: #.## number
END
Проверьте:
> as.regex(pattern2)
<regex> ^([\d]+)\.([\w\W]*?)[\s]*(\d\.[\d]{2})$
См. Демоверсию regex .