在R中的数学比较符号处拆分字符向量
我想用数学比较来拆分表达式,例如在R中的数学比较符号处拆分字符向量,r,regex,R,Regex,我想用数学比较来拆分表达式,例如 unlist(strsplit("var<3", "(?=[=<>])", perl = TRUE)) unlist(strsplit("var==5", "(?=[=<>])", perl = TRUE)) unlist(strsplit("var>2", "(?=[=<>])", perl = TRUE)) unlist(strsplit(“var2”,“(?=[=])”,perl=TRUE)) 结果是:
unlist(strsplit("var<3", "(?=[=<>])", perl = TRUE))
unlist(strsplit("var==5", "(?=[=<>])", perl = TRUE))
unlist(strsplit("var>2", "(?=[=<>])", perl = TRUE))
unlist(strsplit(“var2”,“(?=[=])”,perl=TRUE))
结果是:
[1] "var" "<" "3"
[1] "var" "=" "=" "5"
[1] "var" ">" "2"
[1]“变量”“2”
对于上面的第二个示例,我希望得到[1]“var”“==”“5”
,因此这两个=
应该作为单个元素返回。我需要如何更改正则表达式才能实现这一点?(我已经尝试过对“==”进行分组和量词,但没有任何效果-正则表达式不是我的朋友…使用单词的边界(\\b
)并指定查找的两种可能性:
unlist(strsplit("var==5", "(?=(\\b[^a-zA-Z0-9])|(\\b[a-zA-Z0-9]\\b))", perl = TRUE))
[1] "var" "==" "5"
unlist(strsplit("var<3", "(?=(\\b[^a-zA-Z0-9])|(\\b[a-zA-Z0-9]\\b))", perl = TRUE))
[1] "var" "<" "3"
unlist(strsplit("var>2", "(?=(\\b[^a-zA-Z0-9])|(\\b[a-zA-Z0-9]\\b))", perl = TRUE))
[1] "var" ">" "2"
EDIT2:
完全窃取@Tensibai定义alphanum(+下划线)/非alphanum字符的方式,上述
regex
可以简化为:”(?您可以使用PCRE regex来匹配所需的子字符串:
==|[<>]|(?:(?!==)[^<>])+
看
详细信息:
=
-2=
符号
|
-或
[]
-a
|
-或(?:(?!==)[^])+
-1个或多个字符,而不是
([^]
),它们不启动=
字符序列(令牌)>文本分辨率
[[1]]
[1] “Text1”“==”“text2”“”
[7] “在注释中扩展我的想法,只是为了格式化:
tests=c("var==5","var<3","var.name>5")
regmatches(tests,regexec("([a-zA-Z0-9_.]+)(\\W+)([a-zA-Z0-9_.]+)",tests))
如果您的条目在操作符周围有空间,您可以在每个捕获组之间添加*
,如果没有空间,操作符捕获将获得它们。您是否只想限制到
,@Wiktor,是的,我只想限制在>,sub((.*)([=])(.*))捕获每个部分,“\\2”,“var==55”,perl=TRUE)
或类似的东西。您也可以使用它来拆分strsplit(sub((.*?)([=])(.*),“\\1\\2\\3”,“var==55”,perl=TRUE),”)
但是Wiktors解决方案可能更好如果对您的用例方便,那么总是有解析选项:lapply(unlist(lapply)(c(“var2”),function(e)解析(text=e))),sapply,deparse)
@DavidArenburg,当我在sub()中使用“var>55”
作为x时,你上面的strplit示例生成[1]“var”“>5”“5”
。我使用了([a-zA-Z0-9+)([^a-zA-Z0-9+)([a-zA-Z0-9+)
as regex as operators chars不应该出现在它们的任何一侧。@Tensibai:你的意思是你必须检查这些运算符的两侧是否都有单词chars吗?你可以使用regmatches返回3个捕获组,我认为最好指定它们,使用perl-like For\w也会更好,但我觉得更容易理解比如:regmatches(tests,regexec)([a-zA-Z0-9+)([a-zA-Z0-9+)([a-zA-Z0-9+)([a-zA-Z0-9+)”,tests))
其中tests是一个向量,它会给出每个部分在自己的捕获组中的初始值。(这只是一个备选方案)我想我现在明白你为什么这么说了:OP示例输入字符串是由两部分运算符分隔的短字符串。在这种情况下,我将问题推广到查找任何已知的运算符和其他运算符。呵呵,是的,我保持简单:)很好(我想你不介意我使用你简化我的正则表达式)-pThanks,很好而且很短的解决方案-但是,这个方法不适用于带点的变量名,例如regmatches(“var.name==5”,regexec(“(\\w+)(\\w+)(\\w+),”var.name==5”)
。我尝试了类似于regmatches(“var.name==5”,regexec(\\w+[.]+)(\\w+(\\w+)(\\w+),“var.name==5”)
,但它会吃掉字符向量的“==”部分。@Daniel更正了,只需使用字符类将
添加到允许的字符中即可chars@Daniel这:(\\w |[.]+)
表示来自\w一次或至少一次点的任何字符,也许(\\w |[.])
+可能工作得更好(为了匹配,捕获可能会非常满),但是回溯可能会有问题
[!=]=|[<>]|(?:(?![=!]=)[^<>])+
> text <- "Text1==text2<text3><More here"
> res <- regmatches(text, gregexpr("==|[<>]|(?:(?!==)[^<>])+", text, perl=TRUE))
> res
[[1]]
[1] "Text1" "==" "text2" "<" "text3" ">"
[7] "<" "More here"
tests=c("var==5","var<3","var.name>5")
regmatches(tests,regexec("([a-zA-Z0-9_.]+)(\\W+)([a-zA-Z0-9_.]+)",tests))
[[1]]
[1] "var==5" "var" "==" "5"
[[2]]
[1] "var<3" "var" "<" "3"
[[3]]
[1] "var.name>5" "var.name" ">" "5"