Regex nie operator


124

Czy w Regexes jest operator NOT? Jak w tym ciągu:"(2001) (asdf) (dasd1123_asd 21.01.2011 zqge)(dzqge) name (20019)"

Chcę usunąć wszystko \([0-9a-zA-z _\.\-:]*\), ale nie to, w którym to roku: (2001).

Więc co regex powinna zwracać muszą być: (2001) name.

UWAGA: u mnie coś takiego \((?![\d]){4}[0-9a-zA-z _\.\-:]*\)nie działa ( (20019)jakoś też pasuje ...)


1
Jest String jak powyżej i chcę regex go, że wynik regex jest: (2001) name.
— Sonnenhut

Odpowiedzi:


119

Nie, nie ma bezpośredniego operatora. Przynajmniej nie tak, jak masz nadzieję.

Można jednak użyć ujemnego antycypowania o zerowej szerokości:

\((?!2001)[0-9a-zA-z _\.\-:]*\)

Te (?!...)środki część „tylko pasuje jeśli tekst następujący (stąd: uprzedzona) to nie (stąd: negatywny). Pasujące do tego, ale faktycznie nie zużywają znaki pasuje (stąd: zerowej szerokości).

W rzeczywistości istnieją 4 kombinacje lookarounds z 2 osiami:

  • lookbehind / lookahead: określa, czy uwzględniane są znaki przed, czy za punktem
  • pozytywne / negatywne: określa, czy znaki muszą pasować, czy nie .

Dziękuję?! to też sugerowałem, ale jeśli \((?![\d]{4})[0-9a-zA-z _\.\-:]+\)(20019)
— użyję,

W edycji swojego pytania umieściłeś {4} zewnętrzne spojrzenie w przód, aw tym komentarzu umieściłeś je w środku : który z nich próbowałeś? Ponadto: jeśli chcesz (20019)dopasować, musisz dodać \) wnętrze swojego lookahead:\((?![\d]{4}\))[0-9a-zA-z _\.\-:]+\)
— Joachim Sauer

Z wyrażeniem regularnym powyżej w komentarzu działa. Ale nie rozumiem, że ... Nie rozumiem, dlaczego uciekasz z następnej części. A \((?![\d]{4} -->\)<--)[0-9a-zA-z _\.\-:]+\)zatem, że wspornik nie jest zamknięty, prawda?
— Sonnenhut

Uciekam przed nawiasem zamykającym, )ponieważ chcę dopasować literalny znak )(tak jak robisz to na samym początku i na samym końcu twojego wyrażenia regularnego!). Następnie, po dopasowaniu tego, kończę lookahead, używając nieskrępowanego ).
— Joachim Sauer,

Rozumiem. Te wszystkie postacie trochę mnie zmyliły. Dziękuję Ci.
— Sonnenhut

197

Niezupełnie, chociaż zazwyczaj można zastosować obejście jednego z formularzy

  • [^abc], Który jest znak po znaku nie alub bczy c,
  • lub negatywne lookahead:, po a(?!b)którym anie następujeb
  • lub negatywne lookbehind:, (?<!a)bktóre bnie jest poprzedzonea

Tak, myślę, że negatywne spojrzenie do tyłu to (? <! A) b - odniesienie: regular-expressions.info/lookaround.html
— jankins

10
Ale [^abc]nie powinno oznaczać, alub bczy cnie „nie łańcuch abc”.
— Deszcz

0

Możesz złapać (2001)część i zastąpić resztę niczym.

public static string extractYearString(string input) {
    return input.replaceAll(".*\(([0-9]{4})\).*", "$1");
}

var subject = "(2001) (asdf) (dasd1123_asd 21.01.2011 zqge)(dzqge) name (20019)";
var result = extractYearString(subject);
System.out.println(result); // <-- "2001"

.*\(([0-9]{4})\).* znaczy

  • .* dopasuj wszystko
  • \( dopasuj ( znak
  • ( rozpocząć przechwytywanie
  • [0-9]{4} dowolna cyfra cztery razy
  • ) koniec przechwytywania
  • \) dopasuj ) znak
  • .* cokolwiek (reszta ciągu)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.