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.