r - 需要改进从 26 到 28 种不同格式的 R 正则表达式电话号码提取
问题描述
我正在尝试从 R 中 28 种不同格式的随机文本电话号码中提取。我已经阅读了以前关于 R 正则表达式的帖子,例如\
被替换为\\
,并使用 运行正则表达式运算符perl=TRUE
,所以我已经解决了我的大部分问题。我需要一些调试方面的帮助。
我在 R 中使用以下正则表达式:
medium_regex2 = "(?:\\+?(\\d{1})?-?\\(?(\\d{3})\\)?[\\s-\\.]?)?(\\d{3})[\\s-\\.]?(\\d{4})[\\s-\\.]?"
并运行以下代码:
medium_phone_extract2 <- function(string){
unlist(regmatches(string,gregexpr(medium_regex2,string, perl=TRUE)))
}
medium_phone_extract2(phonenumbers)
该表达式正确地指出了 28 个数字中的 26 个。两种缺失的号码格式是:“+90-555-4443322”“+1.517.3002010”
您将如何改进正则表达式以便正确提取这两种格式?
编辑:我试图提取的完整 28 种格式是:
phonenumbers <- c("05554443322",
"0555 444 3322",
"0555 444 33 22",
"5554443322",
"555 444 3322",
"555 444 33 22",
"905554443322",
"+905554443322",
"+90-555-4443322",
"+1-517-3002010",
"+1-(800)-3002010",
"+1-517-3002010",
"+1.517.3002010",
"000-000-0000",
"000 000 0000",
"000.000.0000",
"(000)000-0000",
"(000)000 0000",
"(000)000.0000",
"(000) 000-0000",
"(000) 000 0000",
"(000) 000.0000",
"000-0000",
"000 0000",
"000.0000",
"0000000",
"0000000000",
"(000)0000000")
howmany_numbers <- length(phonenumbers)
#28
我能够用正则表达式提取的 26 个是:
[1] "05554443322" "0555 444 3322" "5554443322" "555 444 3322" "90555444332"
[6] "+90555444332" "0-555-4443322" "+1-517-3002010" "+1-(800)-3002010" "+1-517-3002010"
[11] "517.3002010" "000-000-0000" "000 000 0000" "000.000.0000" "(000)000-0000"
[16] "(000)000 0000" "(000)000.0000" "(000) 000-0000" "(000) 000 0000" "(000) 000.0000"
[21] "000-0000" "000 0000" "000.0000" "0000000" "0000000000"
[26] "(000)0000000"
解决方案
您可以使用以下正则表达式:
(?:\+?\d{0,3}-?\(?[\s.-]?\d{3}\)?[\s.-]?)?\d{3}[\s.-]?\d{2}\s?\d{2}
如果您只想在不在其他数字内时匹配它,您可以添加(?<!\d)
/(?!\d)
环顾四周以防止在左侧或右侧有数字时匹配:
(?<!\d)(?:\+?\d{0,3}-?\(?[\s.-]?\d{3}\)?[\s.-]?)?\d{3}[\s.-]?\d{2}\s?\d{2}(?!\d)
为确保双方通常的单词边界使用
(?<!\w)(?:\+?\d{0,3}-?\(?[\s.-]?\d{3}\)?[\s.-]?)?\d{3}[\s.-]?\d{2}\s?\d{2}\b
在 R 中,不要忘记将字符串文字中的所有反斜杠加倍:
regex <- "(?<!\\w)(?:\\+?\\d{0,3}-?\\(?[\\s.-]?\\d{3}\\)?[\\s.-]?)?\\d{3}[\\s.-]?\\d{2}\\s?\\d{2}\\b"
要点:
((\\d{1})?|(\\d{2})?|(\\d{3}))?
最好写为\d{0,3}
, 零到三位数的模式(与更线性、直接的模式相比,交替使匹配过程更消耗资源)[\\s.-]
首选,[\\s\\-\\.]
因为连字符最好放在字符类的末尾(无需在那里转义)并注意.
始终匹配.
字符类中的文字(\\d{4}|\\d{2}\\s\\d{2})
可以并且应该重写为\\d{2}\\s?\\d{2}
匹配的 2 位数字,后跟可选的空格,然后是 2 位数字。- 不确定您是否真的想在模式末尾匹配空格、连字符或点,所以我建议
[\\s-\\.]?
在末尾删除。
推荐阅读
- python - 从 N 名玩家中生成每场可能的比赛,并创建 N-1 组,每组 N/2 场比赛
- python - scikit-learn 似乎没有正确构建
- jekyll - Github 页面,使用 jekyll 隐藏两个 markdown 页面
- npm - pnpm 与 winrar。哪些方法可以更快地安装模块?
- typescript - 为什么 Vue 3 无法识别我的 Vuex 商店模块?
- python - 日期时间格式问题
- classloader - 使用 catalog.lookup 从函数转换返回值时发生 ClassCastException
- reactjs - 如何突出显示正在播放的当前歌曲
- html - 并排的单选按钮
- asp.net-mvc - 当类型是“字符串”但需要另一种类型(例如,GUID)时,如何在 Swashbuckle 中格式化字符串值?