正则表达式忽略已经声明的变量初始化

时间:2015-09-19 11:26:39

标签: java regex

如果之前已经捕获了令牌的一部分,我需要一个忽略令牌的正则表达式。

示例

var bold, det, bold=6, sum, k

此处,bold=6应该被忽略,因为已经捕获了bold。 此外,在发生任何匹配之前必须存在var,最后一个标记k不应该跟逗号。只有var和最后一个标记k中的变量后面应加一个逗号。

另一个例子

var bold=6, det, bold, sum, k

此处,bold后面的det应被忽略,因为bold=6已被捕获。

我尝试使用这种模式(?:\\bvar\\b|\\G)\\s*(\\w+)(?:,|$),但它并没有忽略重复的内容。

2 个答案:

答案 0 :(得分:1)

你可以用一个负向前瞻来调整你的正则表达式:

            cd test
            npm install

RegEx Demo

如果在字符串的其余部分跟随一个单词,它将跳过匹配单词,而不是跟踪它已经匹配的内容。

此处(?:\bvar\b|\G)\s*(?:(\w+)(?!.*\b\1\b)(?:=\w+)?|\S+)(?:,|\bk\b) 否定前瞻,如果在输入的RHS上找到相同的单词,将避免匹配单词。 (?!.*\b\1\b)是匹配词的反向引用。

RegEx分手:

\1

答案 1 :(得分:1)

取决于您可以尝试使用哪些信息:

  1. 仅在Java中工作的解决方案,将为您提供变量名称并启动 和结束的错误:

    (?<=var.{0,999})(?<!=)(?!var\b)\b(?<var>\w+)\b(?<!var.{1,999}(?=\k<var>).{1,999}(?=\k<var>).{1,999})
    

    RegexPlanet Demo

    它使用Java正则表达式的丑陋但非常有效的特性:间隔 (x{min,max})在后面。只要你使用间隔 最小和最大长度,您可以在Java正则表达式中使用它。所以与其 .*您可以使用.{0,999}。如果有的话会失败 需要比999更多的char,你可以使用更大的数字,但我 认为在这个问题上没有必要。命名组<var>在此处是可选的,您可以使用普通组在代码中添加它。

    Java实现:

    public class Test{
        public static void main(String[] args){
            String test = "var bold, det, bold=6, sum, k\n" +
                    "var foo=6, abc, foo, xyz, k";
            Matcher matcher = Pattern.compile("(?<=var.{0,999})(?<!=)(?!var)\\b(?<var>\\w+)\\b(?<!var.{1,999}(?=\\k<var>).{1,999}(?=\\k<var>).{1,999})").matcher(test);
            while(matcher.find()){
                System.out.println(matcher.group("var") + "," + matcher.start("var") + "," + matcher.end("var"));
    
            }
    
        }
    }
    
    带输出的

    (变量名,起始索引,结束索引):

    bold,4,8
    det,10,13
    sum,23,26
    k,28,29
    foo,34,37
    abc,41,44
    xyz,51,54
    k,56,57
    
  2. 正则表达式的解释:

    • (?<=var.{0,999}) - 必须以文字var开头,后跟任意
      字符数,但不是新行,
    • (?<!=) - 不应以等号开头,以避免将变量名称和值匹配为不同的匹配项,
    • (?!var\b) - var字后面跟不能,以避免匹配这个字,
    • \b(?<var>\w+)\b - 单独的单词,被捕获到<var>组,
    • (?<!var.{1,999}(?=\k<var>).{1,999}(?=\k<var>).{1,999}) - 匹配的单词前面不能有var字后跟一些字符,包括捕获的字,后跟一些字符,再次包含捕获的字,

    但正如我所写的那样,它只适用于Java。

    1. 如果只需要变量名称,可以使用:

      (?<=var\s|\G,\s)(?<var>\w+)(?=,|$)|(?<=var\s|\G,\s)(?<initialized>[^,\n]+)
      

      DEMO

      获取没有重复的变量名称。但如果你想 开始/结束索引,它将捕获到组的第二次出现 重复的变量名称。