结合正则表达式或'在第一次出现时停止

时间:2014-11-01 23:40:00

标签: regex r

从概念上讲,我想搜索(a|b)并仅获取第一次出现。我知道这是一个懒惰/非贪婪的应用程序,但似乎无法将其与or正确地结合起来。

超出可能会改变很多事情的概念级别ab实际上是更长的模式,但它们已经过单独测试并且工作正常。我在包strapply的{​​{1}}中使用此功能,它本质上可以找到所有匹配项。

我怀疑答案就在某处,但搜索这些东西很难。

详细信息:我正在尝试查找函数表达式gsubfn和函数声明var functionName = function(...)并在function functionName(...)中提取函数的名称(使用javascript解析行) 。 Ra\\s*([[:alnum:]]*)\\s*=*\\s*function\\s*\\([^d|i]b。他们单独工作。单个函数定义将采用一种形式或另一种形式,因此我需要在找到它时停止搜索。

编辑:在此字符串\\s*function\\s*([[:alnum:]]+)\\s*\\([^d|i]中,我只想使用Here is a string of blah blah blah找到第一个'a'或仅使用(a|b)找到第一个'b',当然还有正则表达式我失踪的好东西。

编辑2:非常感谢所有看过这个的人。细节变得很重要,所以我将发布更多信息。以下是我正在搜索的测试线:

(b|a)

以下是我想要使用的两种模式,以及我如何单独使用它们。

dput(lines)
c("var activateBrush = function() {", "    function brushed() { // Handles the response to brushing", 
"    var followMouse = function(mX, mY) { // This draws the guides, nothing else", 
".x(function(d) { return xContour(d.x); })", ".x(function(i) { return xContour(d.x); })"
)

他们按顺序返回:

fnPat1 <- "\\s*function\\s*([[:alnum:]]+)\\s*\\([^d|i]" # conveniently drops 'var'
fnNames <- unlist(strapply(pattern = fnPat1, replacement = paste0, X = lines))
fnPat2 <- "\\s*([[:alnum:]]*)\\s*=*\\s*function\\s*\\([^d|i]" # conveniently drops 'var'
fnNames <- unlist(strapply(pattern = fnPat2, replacement = paste0, X = lines))

我想要做的是同时使用这两种模式。我试过的是

[1] "brushed" "brushed"
[1] "activateBrush" "followMouse"   "activateBrush" "followMouse"

但是返回

fnPat3 <- paste("((", fnPat1, ")|(", fnPat2, "))") # which is (a|b) of the orig. question

我想要的是所有函数名称的向量,即[1] " activateBrush = function() " " function brushed() " 重复是好的,我可以调用c("brushed", "activateBrush", "followMouse")

现在也许这更清楚,也许有人会看到一种完全不同的方法。谢谢大家!

3 个答案:

答案 0 :(得分:1)

匹配第一个ab

> x <- "Here is a string of blah blah blah"
> m <- regexpr("[ab]", x)
> regmatches(x, m)
[1] "a"
> x <- "Here b is a string of blah blah blah"
> m <- regexpr("[ab]", x)
> regmatches(x, m)
[1] "b"

使用sub函数检查正则表达式,正则表达式是否与第一个ab匹配。在下面,使用子函数我刚刚用a替换了第一个b***。我们在这里使用sub函数的优势,即它不会做全局替换。它只替换匹配给定模式或正则表达式的字符的第一次出现。

> x <- "Here is a string of blah blah blah"
> sub("[ab]", "***", x)
[1] "Here is *** string of blah blah blah"
> x <- "Here b is a string of blah blah blah"
> sub("[ab]", "***", x)
[1] "Here *** is a string of blah blah blah"

我们也可以使用gregexprgsub函数。

> x <- "Here is a string of blah blah blah"
> m <- gregexpr("^[^ab]*\\K[ab]", x, perl=TRUE)
> regmatches(x, m)
[[1]]
[1] "a"
> gsub("^[^ab]*\\K[ab]", "***", x, perl=TRUE)
[1] "Here is *** string of blah blah blah"
> x <- "Here b is a string of blah blah blah"
> gsub("^[^ab]*\\K[ab]", "***", x, perl=TRUE)
[1] "Here *** is a string of blah blah blah"

<强>解释

  • ^断言我们刚开始。
  • [^ab]*,否定字符类,匹配任何字符,但不匹配ab零次或多次。我们不会使用[^ab]+,因为在该行的开头可能会出现ab
  • \K会丢弃之前匹配的字符。即,它会删除[^ab]*正则表达式与打印匹配的所有字符。
  • [ab]现在它与以下ab
  • 相匹配

答案 1 :(得分:0)

str_extract()包中尝试stringr

str_extract("b a", "a|b")
[1] "b"
str_extract("a b", "a|b")
[1] "a"
str_extract(c("a b", "b a"), "a|b")
[1] "a" "b"

答案 2 :(得分:0)

在我看来,结合表达式会更容易......

strapply(lines, '(?:var|function)\\s*([[:alnum:]]+)', simplify = c)
# [1] "activateBrush" "brushed"       "followMouse"

(?: ... )Non-capturing group。通过将?:置于您的内部,指定不要捕获该组,而是将事物分组。说,组但不捕获&#34; var&#34;或&#34;功能&#34;然后捕获后面的单词字符。