2012-10-12 31 views
8

Mam dwa wyrażenia regularne, jeden wyciąga nazwy użytkownika z łańcucha csv, a drugi wyciąga e-maile.Scalanie dwóch wyrażeń regularnych

Format łańcuch jest tak:

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

kod dla moich wyrażeń regularnych są takie.

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

Znalazłem kilka qeustions o łączących regexes, ale z odpowiedzi nie były w stanie dowiedzieć się, jak połączyć moje.

moje wydruki pokazać:

"username [email protected]" 

byłbym w stanie wydrukowanie tego samego ze pojedynczego dopasowującego, za pomocą jednego wyrażenia regularnego?

obs: To jest zadanie szkolne, co oznacza, że ​​nie "potrzebuję" ich scalania lub wykonywania, ale chciałbym wiedzieć, czy jest to możliwe i jak trudne będzie to.

Odpowiedz

10

można po prostu użyć Pipe (|) w między multiple Regex, aby dopasować wszystkie z nich: -

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

WYJŚCIE: -

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

UPDATE: -

Jeśli chcesz wydrukować username i email tylko wtedy, gdy oba istnieją, musisz podzielić łańcuch na ;, a następnie zastosować poniższy Regex na każdym z nich.

Oto kod: -

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

WYJŚCIE: -

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

Zgaduję, że OP chce AND REVOXPERS, a NIE LUB je –

+0

@AdamDyga Nie chce zarówno nazwy użytkownika, jak i adresu e-mail z pojedynczego wyrażenia regularnego .. Zobacz: - "czy mógłbym wydrukować to samo z pojedynczego edytora, używając jeden regex? ' –

+0

jest mała różnica, kod OPs (' (matcher.find() && matcher2.find()) 'wymaga, aby zarówno nazwa użytkownika, jak i mail były w ciągu znaków, aby mogły zostać wydrukowane. –

1

Poniższy kod będzie wyodrębnić par. Regex jest dość krótki, ale jestem prawie pewien, że istnieje bardziej elegancki sposób (zawsze jest z 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)); 
     } 
    } 
} 

wyjściowa:

username2 [email protected]
USERNAME3 [email protected]

Wyjaśnienie regex "\\(([^\\)]+)\\)\\s<([^>]+)>":

  • \\(([^\\)]+)\\): grupa spoza ) postaci zamkniętego ( i )
  • \\s: spacja
  • <([^>]+)>: Grupa nie-> znaków zawartych przez < i >
+0

+1 to całkiem proste :) –