KristianMedK
KristianMedK

Reputation: 1841

merge two regular expressions

I have two regular expressions, one pulling out usernames from a csv string, and the other pulling out emails.

the string format is like this:

String s = "name lastname (username) <[email protected]>; name lastname (username) <[email protected]>; name lastname (username) <[email protected]>";

the code for my regular expressions are like this.

Pattern pattern = Pattern.compile("(?<=\\()[^\\)]+");
Matcher matcher = pattern.matcher(s);
Pattern pattern2 = Pattern.compile("((?<=<)[^>]+)");
Matcher matcher2 = pattern2.matcher(s);

while (matcher.find() && matcher2.find()) {
    System.out.println(matcher.group() + " " + matcher2.group());
}

I've found several qeustions about merging regexes, but from the answers i haven't been able to figure out how to merge mine.

my printouts show:

"username [email protected]"

would I be able to print out the same from a single matcher, using one regex?

obs: this is a school assignment, which means i do not "need" to merge them or do any more, but i'd like to know if it is possible, and how difficult it would be.

Upvotes: 12

Views: 28573

Answers (2)

brimborium
brimborium

Reputation: 9512

The following code will extract your pairs. The regex is quite short, but I am almost sure, there is a more elegant way (there always is with regex!). ;)

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) {
        String s = "name1 lastname1 (user1); name2 lastname2 (username2) <[email protected]>; name3 lastname3 (username3) <[email protected]>;";

        Pattern pattern = Pattern.compile("\\(([^\\)]+)\\)\\s<([^>]+)>");
        Matcher matcher = pattern.matcher(s);

        while (matcher.find()) {
            System.out.println(matcher.group(1) + " " + matcher.group(2));
        }
    }
}

Output:

username2 [email protected]
username3 [email protected]

Explanation for the regex "\\(([^\\)]+)\\)\\s<([^>]+)>":

  • \\(([^\\)]+)\\): A group of non-) characters enclosed by ( and )
  • \\s: A space in between
  • <([^>]+)>: A group of non-> characters enclosed by < and >

Upvotes: 1

Rohit Jain
Rohit Jain

Reputation: 213223

You can just use an Pipe (|) in between your multiple Regex, to match all of them : -

    String s = "name lastname (username) <[email protected]>; name lastname
            (username) <[email protected]>; name lastname 
            (username) <[email protected]>;";

    // Matches (?<=\\()[^\\)]+  or  ((?<=<)[^>]+)
    Pattern pattern = Pattern.compile("(?<=\\()[^\\)]+|((?<=<)[^>]+)");
    Matcher matcher = pattern.matcher(s);

    while (matcher.find()) {
        System.out.println(matcher.group());
    }

OUTPUT: -

username
[email protected]
username
[email protected]
username
[email protected]

UPDATE: -

If you want to print username and email only when they both exists, then you need to split your string on ; and then apply the below Regex on each of them.

Here's the code: -

    String s = "name lastname (username) ; 
                name lastname (username) <[email protected]>; 
                name lastname (username) <[email protected]>;";

    String [] strArr = s.split(";");

    for (String str: strArr) {

        Pattern pattern = Pattern.compile("\\(([^\\)]+)(?:\\))\\s(?:\\<)((?<=<)[^>]+)");
        Matcher matcher = pattern.matcher(str);

        while (matcher.find()) {
            System.out.print(matcher.group(1) + " " + matcher.group(2));
        }
        System.out.println();
    }

OUTPUT: -

username [email protected]
username [email protected] // Only the last two have both username and email

Upvotes: 17

Related Questions