特定的正则表达式不适用于R

Sri*_*ine 1 regex r

我正试图找出一个字符串模式; (<double num><space><an operator><space><double num>)例如,(14.0 + 46.0)存在于使用R中的正则表达式的给定字符串中.可以有4个运算符+, - ,*和/.

主要有两种模式.第一个模式的正则表达式标识模式存在于字符串"s"中

#Pattern 1
s = "(14.0 + 46.0)"

#Regex
grep("^\\(-?\\d*\\.\\d{1}\\s[\\+\\-\\*\\/]\\s-?\\d*\\.\\d{1}\\)$", s)
Run Code Online (Sandbox Code Playgroud)

我试图在不同的字符串s1和s2中找到相同的模式.我通过.* 在字符串的开头和结尾添加(任何字符)来修改第一个正则表达式("^.* .*$").我已经在这个在线检查器中检查了正则表达式,但它确实有效.但它在R studio中不起作用.

#Pattern 2
s1 = "((5.0 - 50.0) - 15.0)"
s2 = "(15.0 - (5.0 - 50.0))"

#Regex
grep("^.*\\(-?\\d*\\.\\d{1}\\s[\\+\\-\\*\\/]\\s-?\\d*\\.\\d{1}\\).*$", s1)
Run Code Online (Sandbox Code Playgroud)

ctw*_*els 7

简要

只是为了解释为什么我对你的正则表达式进行了如此多的修改(我实际上只是重写了它).

  1. 你用{1}.虽然这是有效的,但它是多余的,因此{1}可以删除.
  2. 你不需要逃避每个字符在列表中,只有特定的人(即斜线和连字符,但仅连字符时,它不是在设定的开始/结束或一个范围之后 - 所以我把它移到的开始组).
  3. 你的正则表达式允许.1有效,不确定这是否是故意的,如果是,你可以根据自己的喜好编辑我的正则表达式.我只是觉得,一个更正确的解决方案将迫使前一个数.,使得.1无效的,但0.1是否有效.
  4. 您在模式中有重复部分,因此我将这些部分更改为命名捕获组.这样可以根据自己的喜好轻松操作图案.它还允许您在一个位置而不是多个位置定义图案部件.- 递归
  5. 递归是唯一的方法(或C#中的平衡组)我知道你可以正确地确定匹配的打开/关闭标签(在这种情况下是左右括号).g我的模式中的组处理递归.

请参阅此处使用的正则表达式

(?(DEFINE)
  (?<n>[-+]?\d+(?:\.\d+)?)
  (?<a>\s*[-+*\/]\s*)
  (?<g>\((?:(?&n)|(?&g))(?&a)(?:(?&n)|(?&g))\))
)
^(?&g)$
Run Code Online (Sandbox Code Playgroud)

标志: gmx

用法

请参阅此处使用的代码

r <- "(?(DEFINE)(?<n>[-+]?\\d+(?:\\.\\d+)?)(?<a>\\s*[-+*\\/]\\s*)(?<g>\\((?:(?&n)|(?&g))(?&a)(?:(?&n)|(?&g))\\)))^(?&g)$"
x <- c("(14.0 + 46.0)", "((5.0 - 50.0) - 15.0)", "(15.0 - (5.0 - 50.0))", "(15.0 - (5.0 - 50.0)")
grep(r, x, perl=TRUE)
Run Code Online (Sandbox Code Playgroud)

结果

输入

(14.0 + 46.0)
((5.0 - 50.0) - 15.0)
(15.0 - (5.0 - 50.0))
Run Code Online (Sandbox Code Playgroud)

产量

只有如下所示的匹配.

(14.0 + 46.0)
((5.0 - 50.0) - 15.0)
(15.0 - (5.0 - 50.0))
Run Code Online (Sandbox Code Playgroud)

说明

  • (?(DEFINE))子模式定义构造.正则表达式完全忽略了这一点.它被视为var name="value",而您可以通过其名称调用特定模式.
  • (?<n>[-+]?\d+(?:\.\d+)?)子模式n定义有效数字,如下所示
    • [-+]? 匹配集合中任何字符的零或一个 -+
    • \d+ 匹配任何数字一次或多次
    • (?:\.\d+)?匹配零或一个文字点.后跟一个或多个数字
  • (?<a>\s*[-+*\/]\s*)子模式a定义所有有效的算术符号
    • \s* 匹配任意数量的空白字符
    • [-+*\/] 匹配集合中的字符 -+*/
    • \s* 匹配任意数量的空白字符
  • (?<g>\((?:(?&n)|(?&g))(?&a)(?:(?&n)|(?&g))\)) 符合以下
    • \( 匹配文字左括号 (
    • (?:(?&n)|(?&g))匹配ng模式(递归)
    • (?&a)匹配a模式(递归)
    • (?:(?&n)|(?&g))匹配ng模式(递归)
    • \) 匹配文字右括号 )
  • ^(?&g)$ 符合以下
    • ^ 断言该行末尾的位置
    • (?&g)匹配g模式(递归)
    • $ 断言该行末尾的位置