2013-01-18 9 views
12

Próbuję dowiedzieć się, jak używać wyrażeń regularnych C#, aby usunąć wszystkie wystąpienia sparowanych nawiasów z ciągu. Nawiasy i cały tekst między nimi należy usunąć. Nawiasy nie zawsze znajdują się w tej samej linii. Również ich mogą być nawiasy zagnieżdżone. Przykładem ciąg byłobyC# Regex - Jak usunąć wiele sparowanych nawiasów z ciągu

This is a (string). I would like all of the (parentheses 
to be removed). This (is) a string. Nested ((parentheses) should) also 
be removed. (Thanks) for your help. 

pożądany wynik powinien być następujący:

This is a . I would like all of the . This a string. Nested also 
be removed. for your help. 
+1

Czy możesz dodać żądane wyniki? –

+0

Pewnie. Zaktualizuję wpis. –

+1

... lub tutaj: http://stackoverflow.com/questions/133601/can-regular-expressions-be-used-to-match-nested-patterns –

Odpowiedz

21

szczęście .NET pozwala rekursji w regexes (patrz Balancing Group Definitions):

Regex regexObj = new Regex(
    @"\(    # Match an opening parenthesis. 
     (?>    # Then either match (possessively): 
     [^()]+   # any characters except parentheses 
     |    # or 
     \((?<Depth>) # an opening paren (and increase the parens counter) 
     |    # or 
     \) (?<-Depth>) # a closing paren (and decrease the parens counter). 
    )*    # Repeat as needed. 
    (?(Depth)(?!)) # Assert that the parens counter is at zero. 
    \)    # Then match a closing parenthesis.", 
    RegexOptions.IgnorePatternWhitespace); 

W przypadek, w którym ktoś się zastanawia: "licznik parenów" nigdy nie może spaść poniżej zera (<?-Depth> zawodzi inaczej), więc nawet jeśli nawiasy są "zrównoważone", ale nie są poprawnie dopasowane (jak ()))((()), to wyrażenie nie zostanie zmylone.

Aby uzyskać więcej informacji, przeczytaj znakomitą książkę Jeffreya Friedl za "Mastering Regular Expressions" (str. 436)

+0

Bardzo ładne rozwiązanie – msmucker0527

+0

To działało idealnie! Dziękuję Ci! –

+0

@MattBrandon - Jest jeszcze łatwiejszy sposób zrobienia tego w .NET: [Definicja grupy równoważącej] (http://msdn.microsoft.com/en-us/library/bs2twtah.aspx#balancing_group_definition). – JDB

1

Można powtarzalnie zastąpić /\([^\)\(]*\)/g z pustym ciągiem aż nie zostaną znalezione żadne kolejne mecze, choć.

0

Co powiesz na to: Regex Replace wydaje się działać.

string Remove(string s, char begin, char end) 
{ 
    Regex regex = new Regex(string.Format("\\{0}.*?\\{1}", begin, end)); 
    return regex.Replace(s, string.Empty); 
} 


string s = "Hello (my name) is (brian)" 
s = Remove(s, '(', ')'); 

wyjściowy będzie:

"Hello is" 
+0

Myślę, że lepiej byłoby użyć 'Regex.Escape()' over '" \\ {0} "' – JDB

1

Normalnie to nie jest opcja. Jednak Microsoft ma pewne rozszerzenia do standardowych wyrażeń regularnych. Możesz to osiągnąć dzięki Grouping Constructs, nawet jeśli kodowanie jest szybsze niż przeczytanie i zrozumienie wyjaśnienia Microsoftu dotyczącego ich rozszerzenia.

+0

Faktycznie zakończyłem rozwiązywanie tego problemu wcześniej, po prostu kodując algorytm do pracy. Jednak bardzo mnie ciekawi, czy można to zrobić z Regeksem –

+0

dbać o dzielenie się tym algo? – Zibri

Powiązane problemy