在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"