Pytanie Lista wszystkich znaków specjalnych, które muszą zostać zmienione w wyrażeniu regularnym


Próbuję utworzyć aplikację, która pasuje do szablonu wiadomości z komunikatem, który użytkownik próbuje wysłać. Używam wyrażeń regularnych Java do dopasowywania wiadomości. Szablon / wiadomość może zawierać znaki specjalne.

Jak mogę uzyskać pełną listę znaków specjalnych, które muszą zostać zmienione, aby mój regex działał i dopasowywał się w maksymalnych możliwych przypadkach?

Czy istnieje uniwersalne rozwiązanie dla unikania wszystkich znaków specjalnych w regexie Java?


76
2018-01-03 07:14


pochodzenie




Odpowiedzi:


Możesz spojrzeć na javadoc klasy Pattern: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

Jeśli chcesz mieć zwykły znak char, a nie specjalne znaczenie, musisz uciec od oznaczonego tam znaku.

Jako może prostsze rozwiązanie, możesz umieścić szablon pomiędzy \ Q i \ E - wszystko pomiędzy nimi jest uważane za zmienione.


63
2018-01-03 07:44



Jeśli znajdziesz \ Q i \ E trudne do zapamiętania, możesz użyć zamiast Pattern.quote ("...") - mkdev
Szkoda, że ​​ich nie powiedziałeś - Aleksandr Dubinsky
Dlaczego, @AleksandrDubinsky? - Sorin
@Sorin Ponieważ jest to dusza (nie, polityka?) Stack Exchange, aby podać odpowiedź w odpowiedzi, a nie tylko link do zasobu poza siedzibą. Poza tym ta strona również nie ma przejrzystej listy. Listę można znaleźć tutaj: docs.oracle.com/javase/tutorial/essential/regex/literals.html, ale stwierdza: "W niektórych sytuacjach specjalne znaki wymienione powyżej będą nie traktować jak metaznaki ", nie wyjaśniając, co się stanie, jeśli spróbujemy uciec przed nimi. Krótko mówiąc, to pytanie zasługuje na dobrą odpowiedź. - Aleksandr Dubinsky
"wszystko między nimi [\Q i \E] jest uważany za uniknięty " - oprócz innych \Qi \E(które potencjalnie mogą wystąpić w oryginalnym wyrażeniu regularnym). Więc lepiej go używać Pattern.quotejak proponowano tutaj i nie wymyślać koła. - Sasha


  • Znaki Java, które muszą być wyrażone w wyrażeniach regularnych, to:
    \.[]{}()<>*+-=?^$|
  • Dwa z nawiasów zamykających (] i }) muszą być usunięte tylko po otwarciu tego samego rodzaju wspornika.
  • W []-brackets niektóre znaki (np + i -) czasami pracują bez ucieczki.

61
2017-10-07 05:03



Czy istnieje sposób, aby nie uciec, ale pozwolić na te postacie? - Dominika
Ucieczka z postaci oznacza zezwolenie na postać zamiast interpretowania jej jako operatora. - Tobi G.
Unescaped - w ciągu [] nie zawsze działa, ponieważ służy do definiowania zakresów. Bezpieczniej jest z niej uciec. Na przykład wzorce [-] i [-)] dopasuj ciąg - ale nie z [(-)]. - Kenston Choi


Aby uciec, możesz po prostu użyć tego Java 1.5:

Pattern.quote("$test");

Dopasujesz słowo exacty $test


18
2018-05-13 18:02





Według Literały ciągów / Metaznaków stronie dokumentacji, są to:

<([{\^-=$!|]})?*+.>

Poza tym byłoby fajnie, gdyby ta lista była odsyłana gdzieś w kodzie, ale nie wiem, gdzie to mogło być ...


14
2017-12-13 00:53



String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0"); - marbel82
Wzorzec javadoc mówi, że błędem jest użycie ukośnika odwrotnego przed jakimkolwiek alfabetycznym znakiem, który nie oznacza konstrukcji z uniknięciem, ale ukośnik odwrotny może być użyty przed znakiem nie-alfabetycznym, niezależnie od tego, czy ten znak jest częścią konstrukcji bez zmiany znaczenia. Dlatego wystarczy znacznie prostsze wyrażenie regularne: s.replaceAll("[\\W]", "\\\\$0") gdzie \W oznacza znaki nie słowne. - Joe Bowbeer


W przypadku sugestii @ Sorin w dokumentach Java Pattern, wygląda na to, że znaki do ucieczki są co najmniej:

\.[{(*+?^$|

5
2018-02-12 04:17



String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1"); - fracz
) również musi uciekać, i w zależności od tego, czy jesteś w klasie czy poza nią, może być więcej znaków do ucieczki, w takim przypadku Pattern.quote wykonuje całkiem dobrą robotę w ucieczce z napisu do użytku zarówno wewnątrz, jak i na zewnątrz klasy postaci. - nhahtdh


Łącząc to, co wszyscy mówią, proponuję następujące rzeczy, aby lista wyjątków dla RegExp była wyraźnie wymieniona w ich własnych Ciągach i aby nie musieć próbować wizualnie analizować tysięcy "\\". Wydaje mi się, że działa to całkiem dobrze:

final String regExSpecialChars = "<([{\\^-=$!|]})?*+.>";
final String regExSpecialCharsRE = regExSpecialChars.replaceAll( ".", "\\\\$0");
final Pattern reCharsREP = Pattern.compile( "[" + regExSpecialCharsRE + "]");

String quoteRegExSpecialChars( String s)
{
    Matcher m = reCharsREP.matcher( s);
    return m.replaceAll( "\\\\$0");
}

4
2018-04-01 06:22





po drugiej stronie monety powinieneś użyć wyrażenia "non-char", które wygląda tak, jeśli znaki specjalne = allChars - number - ABC - spacja w kontekście twojej aplikacji.

String regepx = "[^\\s\\w]*";

1
2018-01-03 07:39