寻找字符串模式
为了解决这个问题,计算机无需真正理解水果是什么。我们只需要找到一个能描述需
要的模式即可。字面上,我们想要找到所有以一个单词开始,然后一个分号和一个空格,
最后以一个整数而不是单词或者其他符号结尾的行。
正则表达式提供了一系列用于表示模式的符号。上述模式可以被描述成^\w+:\s\d+$,
其中的元符号(meta-symbols)用来表示一类字符。
• ^:这个符号表示一行的开始。
• \w:这个符号表示一个字母。
• \s:这个符号表示一个空格字符。
• \d:这个符号表示一个数字字符。
• $:这个符号表示一行的结束。
此外,"\w+"意味着一个或更多个字母,":"是我们希望在单词后面看到的符号,
"\d+"表示一个或更多个数字字符。这个模式如魔法一样,表达了所有我们需要的情况,
并且排除了所有不需要的情况。
更特殊的是,这个模式匹配了所有如 abc:123 的行,而排除了其他所有的行。为了
在 R 中获取所需的情况,我们需要使用 grep( )来获得匹配模式的字符串:
fruits <- readLines("data/fruits.txt") fruits
## [1] "apple: 20 " "orange: missing"
## [3] "banana: 30" "pear: sent to Jerry"
## [5] "watermelon: 2" "blueberry: 12"
## [7] "strawberry: sent to James"
matches <- grep("^\\w+:\\s\\d+$", fruits)
matches
## [1] 3 5 6
注意到"\"在 R 中需要被写成"\\"来避免转义。然后使用 matches 对 fruits 进行
筛选:
fruits[matches]
## [1] "apple: 20" "banana: 30" "watermelon: 2" "blueberry: 12"
现在我们已经成功地将所需的行从不需要的行中区分出来。匹配模式的行被选中,而
没有匹配模式的行被忽略。
注意到我们指定了一个以"^"开头,以"$"结尾的模式,而不是部分匹配。事实上,正
则表达式默认使用部分匹配,也就是说,如果字符串的任意一部分匹配了模式,那么整个
字符串都被认为匹配了该模式。举个例子,接下来的代码试图找出符合两种模式的字符串:
grep("\\d", c("abc", "a12", "123", "1"))
## [1] 2 3 4
grep("^\\d$", c("abc", "a12", "123", "1"))
## [1] 4
第 1 个模式匹配带有任意数字(部分匹配)的字符串,而第 2 个模式包含"^"和"$",
匹配只有一个数字的字符串。
一旦匹配工作成功,我们可以进入下一步:使用分组来提取数据。