在问题领域中还有许多未解答的问题。除此之外,让我们使用以下数据,其中包含问题中提供的样本数据以进行正匹配,并使用一些附加的样本数据进行负匹配(我正在使用R版本2.14.1(2011-12-22)
):
x <- c("140,000 mostly freeway miles", "173k commuter miles. ", "154K(all highway) miles", "1,24 almost but not mostly freeway miles", "1,2,3,4K MILES")
1,2,3,4K MILES
被添加为负匹配,因为问题将“附近”定义为相隔1-3个单词
,而这个短语中没有任何“附近的单词”。
如果我们使用以下...
sub('[\\d,]+k?\\s+(([^\\s]+\\s+){1,3})miles', '\\1', x, ignore.case = TRUE, perl = TRUE)
我们得到:
[1] "mostly freeway "
[2] "commuter . "
[3] "154K(all highway) miles"
[4] "1,24 almost but not mostly freeway miles"
[5] "1,2,3,4K MILES"
可能不是您想要的结果。由于数据未经过规范化处理,您必须使用非常复杂的正则表达式模式。正如Justin在他的answer中建议的那样,先清理数据,然后进行一些更简单的匹配
。
您可以按以下方式规范化数据:
y <- gsub('\\pP+', ' ', x, perl = TRUE)
y <- gsub('\\s+', ' ', y, perl = TRUE)
y <- gsub('^\\s+|\\s+$', '', y, perl = TRUE)
y <- gsub('(\\d)\\s(?=\\d)', '\\1\\2', y, perl = TRUE)
请参考以下参考资料以获取更多信息。基本上是去除标点符号并确保单词之间只有一个空格。这将使您得到:
y
的内容:
[1] "140000 mostly freeway miles"
[2] "173k commuter miles"
[3] "154K all highway miles"
[4] "124 almost but not mostly freeway miles"
[5] "1234K MILES"
现在删除不符合您要查找的内容的行:
y <- sub('^(?!\\d+k?\\s((?!miles)[^\\s]+\\s){1,3}miles).*$', '', y, ignore.case = TRUE, perl = TRUE)
y
[1] "140000 mostly freeway miles" "173k commuter miles"
[3] "154K all highway miles" ""
[5] ""
最后,获取“相似单词”:
y <- sub('^\\d+k?\\s((?!miles)[^\\s]+(\\s(?!miles)[^\\s]+){0,2})\\smiles', '\\1', y, ignore.case = TRUE, perl = TRUE)
y
[1] "mostly freeway" "commuter" "all highway" ""
[5] ""
可能有更简单的方法来规范化数据,但这里提供了一些正则表达式示例供您尝试。
更多信息,请参见: