【问题标题】:How to check if a given Regex is valid?如何检查给定的正则表达式是否有效?
【发布时间】:2011-02-11 21:19:39
【问题描述】:

我有一个小程序允许用户输入一些正则表达式。之后我想检查这个输入是否是 valid 正则表达式。

我想知道Java中是否有内置方法,但找不到这样的jet。

你能给我一些建议吗?

【问题讨论】:

  • 为什么不在 try/catch 中实例化?
  • 这可能是一个非常无知的问题,到目前为止我只知道我所需要的正则表达式,但是创建一个无效的正则表达式不是很难吗?我不是在谈论一个不正确的,而是一个实际上引发错误的?如果有人有一个例子,我会喜欢这里的一些启发
  • @Nick Craver:")""]""}""?""*""+",所有这些显然都是无效的(不匹配和悬空的元字符)。还有像"x{5,-3}" 这样的东西。大量模式无效。
  • @polygenelubricants - 嗯,有道理,谢谢! @Philipp - 这是一个无效的正则表达式,还是找不到任何有用的东西,但在技术上是正确的?在这里测试它似乎是有效的,即使不是特别有用,我是否遗漏了什么?
  • "lookahead" 是正确的术语 ;)

标签: java regex


【解决方案1】:

这是一个例子。

import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class RegexTester {
    public static void main(String[] arguments) {
        String userInputPattern = arguments[0];
        try {
            Pattern.compile(userInputPattern);
        } catch (PatternSyntaxException exception) {
            System.err.println(exception.getDescription());
            System.exit(1);
        }
        System.out.println("Syntax is ok.");
    }
}

java RegexTester "(capture" 然后输出"Unclosed group",例如。

【讨论】:

    【解决方案2】:

    您可以只Pattern.compile 正则表达式字符串并查看它是否为throws PatternSyntaxException

        String regex = "***";
        PatternSyntaxException exc = null;
        try {
            Pattern.compile(regex);
        } catch (PatternSyntaxException e) {
            exc = e;
        }
        if (exc != null) {
            exc.printStackTrace();
        } else {
            System.out.println("Regex ok!");
        }
    

    这个特别产生以下输出:

    java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
    ***
    ^
    

    关于后视

    这是来自老信任regular-expressions.info的引述:

    关于 Lookbehind 的重要说明

    Java 通过允许有限重复更进一步。您仍然不能使用星号或加号,但可以使用问号和花括号并指定 max 参数。 Java 认识到有限重复可以重写为具有不同但固定长度的字符串的交替

    我认为这句话有错别字,应该说“不同,但长度有限”。无论如何,Java 似乎确实允许在后视中交替使用不同的长度。

        System.out.println(
            java.util.Arrays.toString(
                "abracadabra".split("(?<=a|ab)")
            )
        ); // prints "[a, b, ra, ca, da, b, ra]"
    

    还有一个错误,您实际上可以无限长地向后查看并让它工作,但我不会依赖这种行为。

        System.out.println(
            "1234".replaceAll(".(?<=(^.*))", "$1!")
        ); // prints "1!12!123!1234!"
    

    【讨论】:

    • 日本正是我要找的。谢谢!我很惊讶,我的具有不同查找长度的示例通过了这个测试。 java 正则表达式引擎现在可以处理了吗?!
    • @Philipp:添加了关于后视的内容。查看第二个示例 =)
    • 我也在 regular-expressions.info 上寻找它。很好的发现!
    • 不,这不是错字。他是说每个(理论上的)替代方案都有固定的长度。如果不固定,您将无法确定哪个最长。
    • jap,我在本次讨论顶部某处的评论中的示例有误。多基因润滑剂绝对明白了! java 允许不同的长度,但不能在前瞻/后视中使用星号或加号。他的代码示例也适用于我!
    【解决方案3】:

    试试这个:

    import java.util.Scanner;
    import java.util.regex.*;
    
    public class Solution
    {
          public static void main(String[] args){
          Scanner in = new Scanner(System.in);
          int testCases = Integer.parseInt(in.nextLine());
          while(testCases>0){
            String pattern = in.nextLine();
            if(pattern != null && !pattern.equals("")){
                try{
                    Pattern.compile(pattern);
                    System.out.println("Valid");
                }catch(PatternSyntaxException e){
                    System.out.println("Invalid");
                }
            }
            testCases--;
            //Write your code
         }
      }
     }
    

    使用输入进行测试:
    3
    ([A-Z])(.+)
    [AZa-z
    batcatpat(nat

    【讨论】:

      【解决方案4】:
      public class Solution {
          public static void main(String[] args){
              Scanner in = new Scanner(System.in);
              int testCases = Integer.parseInt(in.nextLine());
              while(testCases>0){
                  String pattern = in.nextLine();
                  try{
                      Pattern.compile(pattern);
                      System.out.println("Valid");
                  }catch(PatternSyntaxException exception){
                      System.out.println("Invalid");
                  }
      
              }
          }
      }
      

      【讨论】:

      • 由于缺少测试用例,它只运行一次 --; , 所以在你的代码中没有使用 while
      • 也改变 testCases 的值,就像这个 testCases——在 catch 块之后,看我的答案更好
      【解决方案5】:

      最明显的做法是在 java.util.regex.Pattern 中使用 compile 方法并 catch PatternSyntaxException

      String myRegEx;
      ...
      ...
      Pattern p = Pattern.compile(myRegEx);
      

      如果 myRegEx 无效,这将抛出 PatternSyntaxException

      【讨论】:

        【解决方案6】:
         public class Solution
         {
         public static void main(String[] args){
          Scanner in = new Scanner(System.in);
          int testCases = Integer.parseInt(in.nextLine());
          while(testCases>0){
             String pattern = in.nextLine();
              try
              {
                  Pattern.compile(pattern);
              }
              catch(Exception e)
              {
                 // System.out.println(e.toString());
                  System.out.println("Invalid");
              }
              System.out.println("Valid");
            }
         }
        }
        

        【讨论】:

        • 由于缺少测试用例,它只运行一次 --; , 所以在你的代码中没有使用 while
        【解决方案7】:

        new String().matches(regEx) 可以直接和try-catch一起使用来判断regEx是否有效。

        boolean isValidRegEx = true;
        try {
            new String().matches(regEx);
        } catch(PatternSyntaxException e) {
            isValidRegEx = false;
        }
        

        【讨论】:

        • 虽然这确实完成了最终结果,但 Pattern.compile(regEx) 更简单(并且正是最终会发生的事情)并且没有任何额外的复杂性。
        猜你喜欢
        • 2013-04-29
        • 1970-01-01
        • 1970-01-01
        • 2013-07-29
        • 2018-03-14
        • 2013-11-07
        • 2013-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多