Match a string against multiple regex patterns

前端 未结 6 1358
甜味超标
甜味超标 2020-12-29 04:46

I have an input string.

I am thinking how to match this string against more than one regular expression effectively.

Example Input: ABCD
相关标签:
6条回答
  • 2020-12-29 05:14

    Here's an alternative. Note that one thing this doesn't do is return them in a specific order. But one could do that by sorting by m.start() for example.

    private static HashMap<String, String> regs = new HashMap<String, String>();
    

    ...

        regs.put("COMMA", ",");
        regs.put("ID", "[a-z][a-zA-Z0-9]*");
        regs.put("SEMI", ";");
        regs.put("GETS", ":=");
        regs.put("DOT", "\\.");
    
        for (HashMap.Entry<String, String> entry : regs.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            Matcher m = Pattern.compile(value).matcher("program var a, b, c; begin a := 0; end.");
            boolean f = m.find();
            while(f) 
            {
                System.out.println(key);
                System.out.print(m.group() + " ");
                System.out.print(m.start() + " ");
                System.out.println(m.end());
                f = m.find();
            }
    
        }   
    }
    
    0 讨论(0)
  • 2020-12-29 05:15

    I'm not sure what effectively means, but if it's about performance and you want to check a lot of strings, I'd go for this

    ...
    static Pattern p1 = Pattern.compile("[a-zA-Z]{3}");
    static Pattern p2 = Pattern.compile("^[^\\d].*");
    static Pattern p3 = Pattern.compile("([\\w&&[^b]])*");
    
    public static boolean test(String s){
       return p1.matcher(s).matches ? true: 
            p2.matcher(s).matches ? true: 
            p3.matcher(s).matches;
    }
    

    I'm not sure how it will affect performance, but combining them all in one regexp with | could also help.

    0 讨论(0)
  • 2020-12-29 05:17

    To avoid recreating instances of Pattern and Matcher classes you can create one of each and reuse them. To reuse Matcher class you can use reset(newInput) method. Warning: This approach is not thread safe. Use it only when you can guarantee that only one thread will be able to use this method, otherwise create separate instance of Matcher for each methods call.

    This is one of possible code examples

    private static Matcher m1 = Pattern.compile("regex1").matcher("");
    private static Matcher m2 = Pattern.compile("regex2").matcher("");
    private static Matcher m3 = Pattern.compile("regex3").matcher("");
    
    public boolean matchesAtLeastOneRegex(String input) {
        return     m1.reset(input).matches() 
                || m2.reset(input).matches()
                || m3.reset(input).matches();
    }
    
    0 讨论(0)
  • 2020-12-29 05:27

    If you have just a few regexes, and they are all known at compile time, then this can be enough:

    private static final Pattern
      rx1 = Pattern.compile("..."),
      rx2 = Pattern.compile("..."),
      ...;
    
    return rx1.matcher(s).matches() || rx2.matcher(s).matches() || ...;
    

    If there are more of them, or they are loaded at runtime, then use a list of patterns:

    final List<Pattern> rxs = new ArrayList<>();
    
    
    for (Pattern rx : rxs) if (rx.matcher(input).matches()) return true;
    return false;
    
    0 讨论(0)
  • 2020-12-29 05:31

    you can make one large regex out of the individual ones:

    [a-zA-Z]{3}|^[^\\d].*|([\\w&&[^b]])*
    
    0 讨论(0)
  • 2020-12-29 05:34

    like it was explained in (Running multiple regex patterns on String) it is better to concatenate each regex to one large regex and than run the matcher only one. This is an large improvement is you often reuse the regex.

    0 讨论(0)
提交回复
热议问题