Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 提取标点符号之间的字符串(如果存在)_R_Regex - Fatal编程技术网

R 提取标点符号之间的字符串(如果存在)

R 提取标点符号之间的字符串(如果存在),r,regex,R,Regex,我试图在:或之后提取字符串和a之前如果第二个标点符号存在,则删除a之后的所有内容如果存在。目标结果是一个数字 当前代码可以在:和之间执行或之后的:但无法处理单独或:单独 另外,gsub(|(100);参见注释)不起作用,我不确定为什么初始的:没有被排除在外,并且需要gsub test以下是一些解决方案 前两个是基础。第一种方法只使用非常简单的正则表达式。第二个比较短,正则表达式只是稍微复杂一点。在这两种情况下,如果没有匹配项,我们都会返回NA,但如果对您很重要,您可以在之后使用0替换NAs(使用

我试图在
之后提取字符串和a
之前
如果第二个标点符号存在,则删除a
之后的所有内容如果存在。目标结果是一个数字

当前代码可以在
之间执行
或之后的
但无法处理
单独或
单独

另外,
gsub(|(100);参见注释)
不起作用,我不确定为什么初始的
没有被排除在外,并且需要gsub


test以下是一些解决方案

前两个是基础。第一种方法只使用非常简单的正则表达式。第二个比较短,正则表达式只是稍微复杂一点。在这两种情况下,如果没有匹配项,我们都会返回NA,但如果对您很重要,您可以在之后使用0替换NAs(使用
ifelse(is.NA(x),0,x)
其中
x
是NAs的答案)

第三个与第二个几乎相同,但在gsubfn中使用Straply。它返回0而不是NA

1)读取。表用分号替换所有冒号,并将其作为分号分隔的字段读取。选取第二个这样的字段,删除第一个非数字及其后的所有内容。然后将剩下的转换为数字

DF <- read.table(text = gsub(":", ";", test), 
  as.is = TRUE, fill = TRUE, sep = ";", strip.white = TRUE)
as.numeric(sub("\\D.*", "", DF$V2))
##[1]  2 30 NA
3)使用与(2)中相同的模式将匹配项转换为数字,如果匹配项为空,则返回0

library(gsubfn)
strapply(test, "^[^:;]+[;:] (\\d+)", as.numeric, simplify = TRUE, empty = 0)
## [1]  2 30  0

这里有一些解决方案

前两个是基础。第一种方法只使用非常简单的正则表达式。第二个比较短,正则表达式只是稍微复杂一点。在这两种情况下,如果没有匹配项,我们都会返回NA,但如果对您很重要,您可以在之后使用0替换NAs(使用
ifelse(is.NA(x),0,x)
其中
x
是NAs的答案)

第三个与第二个几乎相同,但在gsubfn中使用Straply。它返回0而不是NA

1)读取。表用分号替换所有冒号,并将其作为分号分隔的字段读取。选取第二个这样的字段,删除第一个非数字及其后的所有内容。然后将剩下的转换为数字

DF <- read.table(text = gsub(":", ";", test), 
  as.is = TRUE, fill = TRUE, sep = ";", strip.white = TRUE)
as.numeric(sub("\\D.*", "", DF$V2))
##[1]  2 30 NA
3)使用与(2)中相同的模式将匹配项转换为数字,如果匹配项为空,则返回0

library(gsubfn)
strapply(test, "^[^:;]+[;:] (\\d+)", as.numeric, simplify = TRUE, empty = 0)
## [1]  2 30  0
另一种方法:

out <- gsub('(^.+?[;:][^0-9]+)(\\d+)(.*$)|^.+', '\\2', test)
out[out == ''] <- 0
as.numeric(out)

## [1] 2  30  0
out另一种方法:

out <- gsub('(^.+?[;:][^0-9]+)(\\d+)(.*$)|^.+', '\\2', test)
out[out == ''] <- 0
as.numeric(out)

## [1] 2  30  0
out根据OP的描述(斜体是我的):

在:或之后提取字符串;在;如果出现第二个标点符号,则删除a之后的所有内容;如果有。目标结果是一个数字

我认为其他一些建议可能会忽略斜体字的标准。这是OP的测试集,在末尾有一个额外的条件来测试:

test<-c( "Score (ABC): 2 (of 100); see note",
         "Amount of ABC; 30%",
         "Presence of ABC: negative",
         "...and before a ; if the second punctuation is present, then remove everything after a ; if present [so 666 should not be returned]") 
符合OP要求的结果: 如果OP确实需要一个没有匹配项的带零整数,请将sub()替换设置为“
'0\\1”
,并用
包装为.integer()
,如下所示:

as.integer( gsub( pattern='.+?[:;]\\D*?[^;](\\d*).*?;*.*', 
                  replacement='0\\1', 
                   x=test, perl=TRUE) )
结果:

[1]  2 30  0  0
完全在线工作R(R 3.3.2)示例:

Regexp解释 OP只想在字符串中找到一个匹配项,这样
sub()
函数就可以正常工作

使用<代码>子()/<代码>的方法是生成与所有字符串匹配的模式,但如果满足条件,则在中间使用捕获组捕获零个或更多个数字。p> 模式

+?[:;]\\D*?[^;](\\D*).*?;**如下所示

  • +?
    在一次和无限次之间匹配任何字符(行终止符除外)
    +
    尽可能少地匹配,根据需要扩展(惰性)
  • [:;]
    在方括号之间匹配列表中的单个字符,在本例中为
  • \\D
    匹配任何非数字字符(等于[^0-9])
  • *?
    量词
    *
    在零次和无限次之间匹配
    尽可能少的次数,根据需要展开(惰性)
  • [^;]
    作为方括号之间的第一个字符的
    ^
    表示:在方括号之间匹配列表中不存在的单个字符,在这种情况下,匹配任何不属于
    的字符
  • (\d*)
    曲线括号之间的所有内容都是一个捕获组-这是第一个捕获组:
    \\d*
    在零次和无限次之间匹配一个数字(等于[0-9]),尽可能多地匹配(贪婪)
  • *匹配
    字符
    *
    介于零次和无限次之间[因此,不必存在,但如果存在则匹配:这是根据OP请求排除第二个分隔符之后的任何内容的关键]
  • *
    在零次和无限次之间匹配任意字符
    *
    ,尽可能多地匹配(贪心)[因此将所有字符都拾取到行的末尾]
替换=
\\1
指的是我们模式中的第一个捕获组。我们用我们在捕获组中发现的东西替换所有与模式匹配的东西<代码>\\d*
不能匹配任何数字,因此如果在我们期望的位置没有找到数字,则将返回空字符串。

根据OP的描述(斜体是我的):

在:或之后提取字符串;在;如果出现第二个标点符号,则删除a之后的所有内容;如果有。目标结果是一个数字

我认为其他一些建议可能会忽略斜体字的标准。这是OP的测试集,在末尾有一个额外的条件来测试:

test<-c( "Score (ABC): 2 (of 100); see note",
         "Amount of ABC; 30%",
         "Presence of ABC: negative",
         "...and before a ; if the second punctuation is present, then remove everything after a ; if present [so 666 should not be returned]") 
符合OP要求的结果: 如果OP确实需要一个没有匹配项的带零整数,请将sub()替换设置为“
'0\\1”
,并用
包装为.integer()
,如下所示:

as.integer( gsub( pattern='.+?[:;]\\D*?[^;](\\d*).*?;*.*', 
                  replacement='0\\1', 
                   x=test, perl=TRUE) )
结果:

[1]  2 30  0  0
完全在线工作R(R 3.3.2)示例: