1

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");
    }

5 Answers 5

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

You can use Pattern.quote("Q$(w+)E") method to add Pattern to pass in compile method.

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

Comments

1

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

2 Comments

Thank you for the quick reply. It is working for two args only. But, for below, it is not working. <code> final String command "somescript.file $(ABC_PATH1) $(ENV_PATH2) $(ENV_PATH3) <may be other args too here>"; </code>
Sorry, It was my mistake. It is working. Thank you, @Krzysztof Cichocki
1

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+\\)";

Comments

1

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");
      }
   }
}

2 Comments

Thank you for the reply LppEdd. But, actually I am replacing the matched pattern with Environment variables. And I don't want to change that implementation.(It was already handled to replace matched pattern) My requirement is, after resolving all variables which are present in my list (WORDS in your code), again have to cross check whether all $(XXX) are resolved. Something like this: cmd = "somescript.file $(ABC_PATH1) $(ENV_PATH2) $(ENV3)"; $(ABC_PATH1) >>> "WORD1", $(ENV_PATH2) >>> "WORD2" $(ENV3) >>> Nothing is available for this.
Hi! I'm still not sure what you want to do. Do you need to display the various Placeholders?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.