7

I have a string which may have one of two formats:

  • (someName,true); (where someName can be any combination of letters and numbers, and after the comma we have either true or false)
  • (someName,true), (anything,false), (pepe12,true); and in this case, we can have as many parenthesis groups as can be, but they are separated with a comma plus white space.

Given the following test set:

(hola,false);
comosoy12,true);
caminare)
true,comoestas

I used the following regex ^\(.*,(true|false)[)][;$] and got my expected result of true, false, false, false (quick check here). But I cannot seem to come up with the regex for the following cases:

(someName,true), (anything,false), (pepe12,true);
(hola,false);
comosoy12,true);
(batman,true), (kittycat,false);
(batman,true); (kittycat,false);

Which should return true, true, false, true, false.

1
  • s.matches("^\\(\\w+,(?:true|false)\\)(?:, \\(\\w+,(?:true|false)\\))*;") or s.matches("^\\(\\w+,(?:true|false)\\)(?:,\\s+\\(\\w+,(?:true|false)\\))*;") Commented Sep 13, 2019 at 9:05

1 Answer 1

8

You may use

^\(\w+,(?:true|false)\)(?:,\s*\(\w+,(?:true|false)\))*;$

See the regex demo. Note .* in your pattern can match any 0+ chars other than line break chars while you want to match letters and digits, thus I suggest \w (note it also matches _) or, you may use \p{Alnum} or [A-Za-z0-9].

Pattern details

  • ^ - start of string
  • \(\w+,(?:true|false)\) - block: (, 1+ word chars (or alhphanumeric if you use [a-zA-Z0-9] or \p{Alnum}), ,, true or false
  • (?:,\s*\(\w+,(?:true|false)\))* - 0 or more sequences of
    • , - comma
    • \s* - 0+ whitespaces
    • \(\w+,(?:true|false)\) - block pattern
  • ; - a ; char
  • $ - end of string

In Java, you may build the regex dynamically and since you want a full string match with matches, you may discard the initial ^ and final $ anchors:

String block = "\\(\\w+,(?:true|false)\\)";
String regex = block + "(?:,\\s+" + block + ")*;";
bool result = s.matches(regex);

See Java demo online:

List<String> strs = Arrays.asList("(someName,true), (anything,false), (pepe12,true);","(hola,false);","comosoy12,true);", "(batman,true), (kittycat,false);", "(batman,true); (kittycat,false);");
String block = "\\(\\w+,(?:true|false)\\)";
String regex = block + "(?:,\\s+" + block + ")*;";
Pattern p = Pattern.compile(regex);
for (String str : strs)
    System.out.println(str + " => " + p.matcher(str).matches());

Output:

(someName,true), (anything,false), (pepe12,true); => true
(hola,false); => true
comosoy12,true); => false
(batman,true), (kittycat,false); => true
(batman,true); (kittycat,false); => false
Sign up to request clarification or add additional context in comments.

2 Comments

This one is great! What if I want to allow _ (underscore) and - (dash) on the name where I put the .*?
@Mel \w matches an underscore. To allow -, use [\w-]+ instead of \w+.

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.