如何在正则表达式中匹配n个单词?

时间:2012-02-06 10:01:46

标签: regex r

在我挠头和广泛的谷歌搜索之后,我似乎无法做到这一点。

我有这个示例字符串:

  

test =“预计真实销售额将比50%高出60%   上一年报告的那些。主要原因是   等等等等。假的销售预计将介于两者之间   降低25%和35%。“

我正在试图确定“真实”的销售额是高还是低。使用R和'stringr'库,我正在尝试如下:

test = "true sales are expected to be between 50% and 60% higher than those reported for the previous corresponding year. the main reason is blah blah. the fake sales are expected to be in the region of between 25% and 35% lower."
positive.regex = "(sales).*?[0-9]{1,3}% higher"
negative.regex = "(sales).*?[0-9]{1,3}% lower"

产生以下结果:

  

str_extract(测试,positive.regex)       [1]“预计销售额将增长50%至60%”   str_extract(测试,negative.regex)       [1]“预计销售额将在50%至60%之间       高于上一年度报告的数字。主要原因是等等。预计假销售额将在25%至35%之间降低“

我正试图找到一种方法来限制(销售)与'% higher''% lower'之间匹配的字数,以便负正则表达式不匹配。我知道我需要更换'。*?'使用与整个单词匹配的内容,而不是字符,并将这些单词的数量限制为3-5,我该怎么做?

4 个答案:

答案 0 :(得分:2)

您必须确保在正则表达式的higher部分中不出现lower.*?字样。一种方法是使用否定的lookahead assertion

positive.regex = "sales(?:(?!higher|lower).)*[0-9]{1,3}% higher"
negative.regex = "sales(?:(?!higher|lower).)*[0-9]{1,3}% lower"

<强>解释

(?:      # Match...
 (?!     #  (unless we're at the start of the word
  higher #   "higher"
 |       #   or
  lower  #   "lower"
 )       #  )
 .       # any character
)*       # Repeat any number of times.

答案 1 :(得分:1)

这使用gsubfn包。它找到指示的正则表达式的出现,然后检查匹配是否小于或等于max.width个单词,只返回匹配,如果是这样的话:

library(gsubfn)

max.words <- 11
num.words <- function(x) length(strsplit(x, "\\s+")[[1]])

strapply(test, "(sales.*?\\d+% (higher|lower))", function(x, y) 
    if (num.words(x) <= max.words) x)

如果需要,我们可以扩展if语句,将其限制为"higher""lower"

strapply(test, "(sales.*?\\d+% (higher|lower))", function(x, y) 
    if (num.words(x) <= max.words && y == "higher") x)

这个函数可以用这样的公式表示法编写(在上一个例子的情况下):

strapply(test, "(sales.*?\\d+% (higher|lower))", 
    ... ~ if (num.words(..1) <= max.words && ..2 == "higher") ..1)

答案 2 :(得分:0)

为什么不使用与两者匹配的正则表达式?然后,您可以检查最后一个单词是“更高”还是“更低”。

r <- "sales.*?[0-9]{1,3}% (higher|lower)"
str_match_all(test,r)

答案 3 :(得分:0)

如果您只是使用它:

true sales.+higher

......它会起作用,但事实上,如果后来句子说“假销售额更高”,它可能会最终匹配。所以要解决这个问题,请使用:

true sales.+higher.+fake

如果以上匹配,那么真正的销售额确实更高。如果符合以下条件:

真实的销售。+更低。+假的

然后真正的销售额会降低。当然有点粗糙。您可能希望用[\ s \ S]替换点以包含换行符。希望这会有所帮助。