简体   繁体   中英

Pattern matching issue in Java

I am poor in Regular Expressions. I googled and got basic understanding of it.

I have below requirement: My command may contain some strings with "$(VAR_NAME)" pattern. I need to find out whether it has such type of strings or not. If so, I have to resolve those(I know what should I do, if such strings are there). But, problem is, how to find whether command has strings with "$(VAR_NAME)" pattern. There might be multiple or zero of such string patterns in my command.

As per my knowledge, I have written below code. If I use, 'pattern1' , in below code, it is matching. But, not with 'pattern' Can someone help in this?

Thank you in advance.

    final String command = "somescript.file $(ABC_PATH1) $(ENV_PATH2) <may be other args too here>";
    final String pattern = "\\Q$(\\w+)\\E";
    //final String pattern1 = "\\Q$(ABC_PATH1)\\E";

    final Pattern pr = Pattern.compile(pattern);
    final Matcher match = pr.matcher(command);
    if (match.find())
    {
        System.out.println("Found value: " + match.group(0));
    }
    else
    {
        System.out.println("NO MATCH");
    }

您可以使用Pattern.quote("Q$(w+)E")方法添加Pattern以传入编译方法。

 final Pattern pr = Pattern.compile(Pattern.quote("Q$(w+)E"));

I think you are overcomplicating the problem.
Since $( is a reserved "word", just do this to check if there are occurrences:

command.indexOf("$(");

Usage example:

public class Test
{
   private static final String[] WORDS;

   static {
      WORDS = new String[] {
            "WORD1",
            "WORD2"
      };
   }

   public static void main(final String[] args) {
      String command = "somescript.file $(ABC_PATH1) $(ENV_PATH2)";

      int index = 0;
      int i = 0;

      while (true) {
         index = command.indexOf("$(", index);

         if (index < 0) {
            break;
         }

         command = command.replace(command.substring(index, command.indexOf(")", index) + 1), WORDS[i++]);
      }
   }
}

It prints: somescript.file WORD1 WORD2

Sticking to the original source:

public class Test
{
   public static void main(final String[] args) {
      final String command = "somescript.file $(ABC_PATH1) $(ENV_PATH2)";
      int index = 0;
      int occurrences = 0;

      while (true) {
         index = command.indexOf("$(", index);

         if (index < 0) {
            break;
         }

         occurrences++;
         System.out.println(command.substring(index, command.indexOf(")", index++) + 1));
      }

      if (occurrences < 1) {
         System.out.println("No placeholders found");
      }
   }
}

Using \\Q and \\E will mean you cannot setup a capture group for the variable name because the round brackets will be interpreted literally.

I'd probably do it like this, just escape the outer $, ( and ).

Also if you need multiple matches you need to call find() multiple times, I've used a while loop for this.

final String command = "somescript.file $(ABC_PATH1) $(ENV_PATH2) <may be other args too here>";
final String pattern = "\\$\\((\\w+)\\)";

final Pattern pr = Pattern.compile(pattern);
final Matcher match = pr.matcher(command);
while (match.find()) {
    System.out.println("Found value: " + match.group(1));
}

Output

Found value: ABC_PATH1
Found value: ENV_PATH2

The pattern could look like:

public static void main(String[] args) {
    final String command = "somescript.file $(ABC_PATH1) $(ENV_PATH2) <may be other args too here>";
    final String pattern = "\\$\\((.*?)\\)";
    // final String pattern1 = "\\Q$(ABC_PATH1)\\E";

    final Pattern pr = Pattern.compile(pattern);
    final Matcher match = pr.matcher(command);

    while (match.find()) {
        System.out.println("Found value: " + match.group(1));
    }

}

prints:

    Found value: ABC_PATH1
    Found value: ENV_PATH2

The problem is that quoting applies to the \\w+ in the pattern as well and I think it was not the intention (as it is, it matches the string "cmd $(\\w+)" that includes the backslash, 'w' and plus sign).

The pattern can be replaced with:

    final String pattern = "\\$\\(\\w+\\)";

Or, if you'd still like to use \\Q and \\E on the first part:

    final String pattern = "\\Q$(\\E\\w+\\)";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM