How do I make a regular expression that matches text with an open parenthesis only not preceded by a space?

Viewed 42

How do I craft a regular expression with a group that includes text with an open parenthesis not preceded by a space, but does not include an open parenthesis preceded by a space (and everything after that)?

Some examples:

Matching: "Yasmani Grandal (1B 1.84)"
Would return: "Yasmani Grandal"

Matching: "J.T. Realmuto"
Would return: "J.T. Realmuto"

Matching: "WillD. Smith(LAD)"
Would return: "WillD. Smith(LAD)"

Matching: "Adley(round/1/2019) Rutschman"
Would return: "Adley(round/1/2019) Rutschman"

Attempted solutions:

(.+)(?:\s\(.*)

This regular expression returns the "Yasmani Grandal" as group 1 when matching "Yasmani Grandal (1B 1.84)", but doesn't match "J.T. Realmuto" because the second (non-matching) group is not optional.

But if I make it optional: (.+)(?:\s\(.*)?

...then group 1 when matching "Yasmani Grandal (1B 1.84)" is ""Yasmani Grandal (1B 1.84)".

3 Answers

You may use

^(.*?)(?:\s+\(.*\))?$

See the regex demo

Details

  • ^ - start of string
  • (.*?) - Capturing group 1: any 0 or more chars other than line break chars as few as possible
  • (?:\s+\(.*\))? - an optional non-capturing group matching 1 or 0 occurrences of
    • \s+ - 1+ whitespaces
    • \( - a ( char
    • .* - any 0 or more chars other than line break chars as many as possible
    • \) - a ) char
  • $ - end of string.

You could use the following regular expression to convert matches to empty strings. (I've escaped the leading space merely for readability.)

\ +\((?!.* \)).*

The converted string is presumably what you want, so there seems no point to saving it to a capture group. If you need to capture the part of the string that is converted to an empty string, replace .* with (.*).

As this regex contains nothing more exotic the a positive lookahead it should work with most regex engines.

Start your engine!

The regex engine performs the following operations.

\ +        : match 1+ spaces
\(         : match '('
(?!.* \))  : use a negative lookahead to assert the remainder of
             the line does contain the string ' )'`
.*         : match 0+ characters other than line terminators

I've assumed you want to remove all spaces preceding the left parenthesis that is preceded by at least one space. If, for example, the string were:

Yasmani Grandal      (1B 1.84)
               ^^^^^^^^^^^^^^^

the part identified by the party hats would be converted to an empty string.

Can you try this and let me know if this works?

(.+)\s\(.*

public class HelloWorld{

     public static void main(String []args){
        String[] names = new String[] {"Yasmani Grandal (1B 1.84)","J.T. Realmuto","WillD. Smith(LAD)","Adley(round/1/2019) Rutschman"};
        
        for (String in : names)
        System.out.println(in.replaceAll("(.+)\\s\\(.*","$1"));
     }
}

Please note I wrote a minimal expression for this. You can extend it as per your additional requirements. The above code works just fine.

Related