2009-03-10 10 views
19

Powiedz, że mam ciąg "User Name: firstname.surname" zawarty w większym ciągu, jak mogę użyć wyrażenia regularnego, aby uzyskać część firstname.surname?Zwracam tylko część dopasowania z wyrażenia regularnego

Każda z wypróbowanych metod zwraca ciąg znaków "Nazwa użytkownika: imię.nazwisko", a następnie muszę zastąpić ciąg znaków w "Nazwa użytkownika:" pustym ciągiem znaków.

Czy można tu użyć referencji?

Edit:

Im dłuższy łańcuch może zawierać „Nazwa konta: firstname.surname” więc dlaczego chcę dopasować „Nazwa użytkownika:” część napisu aswell tylko dostać tę wartość.

Odpowiedz

31

Lubię używać nazwanych grup:

Match m = Regex.Match("User Name:first.sur", @"User Name:(?<name>\w+\.\w+)"); 
if(m.Success) 
{ 
    string name = m.Groups["name"].Value; 
} 

stawianie ?<something> na początku grupy w nawiasach (np (?<something>...)) pozwala uzyskać wartość z meczu z wykorzystaniem something jako klucz (np m.Groups["something"].Value)

Jeśli nie chcesz iść do kłopotów z nazywania grup, można powiedzieć

Match m = Regex.Match("User Name:first.sur", @"User Name:(\w+\.\w+)"); 
if(m.Success) 
{ 
    string name = m.Groups[1].Value; 
} 

i po prostu uzyskaj pierwszą rzecz, która pasuje. (Zauważ, że pierwszy nawiasach grupa jest w indeksie 1; całe wyrażenie, które dopasowuje się w indeksie 0)

+1

To jest super, dzięki. –

2

Wszystkie regularne biblioteki ekspresyjne Mam stosowane pozwalają na zdefiniowanie grupy w wyrażeniu regularnym użyciu nawiasów, a następnie uzyskać dostęp do tej grupy z wyniku.

Więc Twój regexp może wyglądać następująco: Nazwa użytkownika: (. [. ^] [^.])

pełna mecz grupy 0. Część, która pasuje wewnątrz nawiasów jest grupa 1.

2

Bądź grupę o nawiasach, a następnie dostać go z kolekcji Match.Groups, tak:

string s = "User Name:firstname.surname"; 
Regex re = new Regex(@"User Name:(.*\..*)"); 
Match match = re.Match(s); 
if (match.Success) 
{ 
    MessageBox.Show(match.Groups[1].Value); 
} 

(uwaga: pierwsza grupa, z indeksem 0, to cały mecz)

6

You cou Spróbuję również koncepcji "obejścia". Jest to rodzaj asercji o zerowej szerokości, co oznacza, że ​​będzie pasować do postaci, ale nie będzie przechwytywał ich w wyniku.

W twoim przypadku możemy mieć pozytywny lookbehind: chcemy, aby to, co znajduje się za docelowym łańcuchem "firstname.surname" było równe "User Name:".

Pozytywna operator lookbehind: (? < = StringBehind) StringWeWant

Można to osiągnąć w ten sposób, na przykład (trochę przykład Java, wykorzystując ciąg wymienić):

String test = "Account Name: firstname.surname; User Name:firstname.surname"; 
String regex = "(?<=User Name:)firstname.surname"; 
String replacement = "James.Bond"; 
System.out.println(test.replaceAll(regex, replacement)); 

Zastępuje tylko ciągi "firstname.surname" poprzedzone "User Name:" bez zastępowania samego "User Name:" - które nie jest zwracane przez wyrażenie regularne, tylko dopasowane.

WYJŚCIE: Nazwa konta: firstname.surname; Nazwa użytkownika: James.Bond

Oznacza to, że jeśli język używasz obsługuje tego rodzaju operacji

+0

pozytywny operator lookbehind był dokładnie tym, czego potrzebowałem. Więcej informacji na ten temat tutaj: http://www.regular-expressions.info/lookaround.html – Paul

+0

To powinna być odpowiedź. – GregoryBrad