2013-03-06 16 views
5

orginal pytanie usuniętyRegularne wyrażenie warunkowe formatowanie ciąg numerycznego


szukam wyrażenia regularnego, które będą sformatować ciąg zawierający specjalnych znaków, znaków i liczb w ciąg zawierający tylko cyfry. Istnieją specjalne przypadki, w których nie wystarczy zastąpić wszystkie nie-numeryczne znaki znakiem "" (puste).

1.) Zero w nawiasach.

  • Jeśli w nawiasie są tylko zera (0), należy je usunąć, jeśli jest to pierwsza para wsporników. (Nie należy usuwać drugiej pary wsporników zawierającej tylko zera)

2.) Prowadzące zero.

  • Wszystkie prowadzące powinny zostać usunięte zera (wsporniki) ignoruje

przykładów dla lepszego zrozumienia:

  • 123 (0) 123 would be 123123 (zero removed)
  • (0) 123 -123 would be 123123(zero and all other non-numeric characters removed)
  • 2(0) 123 (0) would be 21230 (first zero in brackets removed)
  • 20(0)123023(0) would be 2(first zero in brackets removed)
  • 00(0)1 would be 1(leading zeros removed)
  • 001(1)(0) would be 110 (leading zeros removed)
  • 0(0)02(0) would be 20 (leading zeros removed)
  • 123(1)3 would be 12313 (characters removed)
+0

Jaki język/smak regex? –

+0

@ExplosionPills C# .NET flavor (zobacz tagi) ... – Virtlink

+1

'[^ \ d]' jest wyrażeniem regularnym dla wszystkiego, co * nie jest * cyfrą, więc nie jestem pewien, w jaki sposób zamierzasz używać tego wyrażenia regularnego. –

Odpowiedz

5

można użyć lookbehind dopasować (0) tylko wtedy, gdy jest to nie na początku ciąg, i zastąp ciąg pusty, jak robisz.

(oryginalne rozwiązanie usunięty)


Updated ponownie aby odzwierciedlić nowe wymagania

zestawienia zer, zapałki (0) tylko wtedy, gdy jest to pierwszy w nawiasach pozycja, a mecze wszelkie znaki nie będące cyframi:

^[0\D]+|(?<=^[^(]*)\(0\)|\D 

Należy zauważyć, że większość silników wyrażeń regularnych nie obsługuje funkcji zmiany długości zmiennej (np. Użycie kwantyfikatorów, takich jak *), więc działa to tylko w kilku silnikach wyrażeń regularnych - .NET jest jednym z nich.

^[0\D]+  # zeroes and non-digits at start of string 
|   # or 
(?<=^[^(]*) # preceded by start of string and only non-"(" chars 
\(0\)  # "(0)" 
|   # or 
\D   # non-digit, equivalent to "[^\d]" 

(testowane na regexhero.net)


Zmieniono wymagania i dodaje kilka razy. W przypadku wielu reguł, takich jak ten, prawdopodobnie lepiej jest kodować je indywidualnie. Może być skomplikowane i trudne do debugowania, jeśli jeden warunek pasuje i powoduje, że inny warunek nie pasuje, gdy powinien. Na przykład w oddzielnych krokach:

  1. Usuń potrzebne elementy w nawiasach.
  2. Usuwanie znaków nie będących cyframi.
  3. Usuń wiodące zera.

Ale jeśli absolutnie potrzebujesz tych trzech warunków, wszystkie dopasowane do jednego wyrażenia regularnego (niezalecane), oto jest.

+0

To była poprawna odpowiedź na moje pytanie, ale właśnie odkryłem, że moje pytania nie były wystarczająco precyzyjne. – Florian

+0

@ Anubis1233 Zaktualizowano ponownie, aby odzwierciedlić zmieniające się wymagania. – Wiseguy

+0

@ Anubis1233 Po raz kolejny zaktualizowano, aby odzwierciedlić zmienione i dodatkowe wymagania. W tym momencie prawdopodobnie powinieneś zastosować te wymagania osobno. – Wiseguy

1

Ten regex powinny być całkiem blisko jednej którego szukasz.

(^[^\d])|([^\d](0[^\d])?)+ 

(można zastąpić wszystko co jest złowionych przez pusty ciąg)

EDIT:

Żądanie ewoluowała i obecnie należy do kompleksu treatd z jednym przejściu. Zakładając, że zawsze ale przestrzeń przed grupą uchwytu, można korzystać z tych przepustek (utrzymanie tej kolejności):

string[] entries = new string[7] { 
    "800 (0) 123 - 1", 
    "800 (1) 123", 
    "(0)321 123", 
    "1 (0) 1", 
    "1 (12) (0) 1", 
    "1 (0) (0) 1", 
    "(9)156 (1) (0)" 
}; 
foreach (string entry in entries) 
{ 
    var output = Regex.Replace(entry , @"\(0\)\s*\(0\)", "0"); 
    output = Regex.Replace(output, @"\s\(0\)", ""); 
    output = Regex.Replace(output, @"[^\d]", ""); 
    System.Console.WriteLine("---"); 
    System.Console.WriteLine(entry); 
    System.Console.WriteLine(output); 
} 
+0

Czytanie mojego regex później, uważam, że powinien go usunąć, ale nie miałem żadnego problemu z RegExr, moje złe. W każdym razie, teraz wniosek ewoluował i naprawdę zaczyna być trudny! – zessx

1

Regeksy są znacznie prostsze, jeśli można użyć wielu przejść. Myślę, że można zrobić pierwszy podaje do upuścić (0), jeżeli nie jest to pierwsza rzecz, na sznurku, a następnie go z odpędzania z non-cyfry:

var noMidStrParenZero = Regex.Replace(text, "^([^(]+)\(0\)", "$1"); 
var finalStr = Regex.Replace(noMidStrParenZero, "[^0-9]", ""); 

unika dużo regex szaleństwa, i w pewnym stopniu jest to samo-dokumentowanie.

EDYCJA: ta wersja powinna również działać z Twoimi nowymi przykładami.

0
(?:  # start grouping 
    ^ # start of string 
    | # OR 
    ^\(# start of string followed by paren 
    | # OR 
    \d # a digit 
)  # end grouping 
(0+) # capture any number of zeros 
|  # OR 
([1-9]) # capture any non-zero digit 

This works for all of your example strings, ale cały wyraz nie pasuje do ( następuje przez zero. Możesz użyć Regex.Matches, aby uzyskać kolekcję meczów za pomocą dopasowania globalnego, a następnie dołączyć wszystkie dopasowane grupy do ciągu, aby uzyskać tylko liczby (lub po prostu usunąć wszystkie numery bez numerów).