Zastępowanie wszystkich znaków niealfanumerycznych pustymi ciągami


197

Próbowałem tego użyć, ale nie działało

return value.replaceAll("/[^A-Za-z0-9 ]/", "");

36
Chłopaki, zapominacie, że istnieją alfabety inne niż łaciński.
Mateva

2
Ale jeśli chcesz na przykład sprawdzić nazwę hosta, dobrze byłoby wykluczyć nieprawidłowe alfabety.
Gurnard,

Odpowiedzi:


245

Zastosowanie [^A-Za-z0-9].

Uwaga: usunięto spację, ponieważ zwykle nie jest to uważane za alfanumeryczne.


10
Przestrzeń na końcu klasy postaci również nie powinna.
Andrew Duffy,

6
Prawdopodobnie jest przyzwyczajony do programowania w PHP.
William

10
@William - to niefortunne, że PHP otrzymuje teraz kredyt na PCRE
Thomas Dignan

reg exp jest ok, po prostu usuń „/” z ciągu wyrażeń regularnych z value.replaceAll („/ [^ A-Za-z0-9] /”, „”); to value.replaceAll („[^ A-Za-z0-9]”, „”); nie potrzebujesz
znaku

128

Próbować

return value.replaceAll("[^A-Za-z0-9]", "");

lub

return value.replaceAll("[\\W]|_", "");

4
Z podkreśleniami,return value.replaceAll("\\W", "");
erickson,

Oczywiście. Kompilatory są świetne w wykrywaniu tego typu rzeczy.
Andrew Duffy,

1
Drugi nie odpowiada na pytanie. Co ze znakami takimi jak: / \ itp?
WW.

67

Należy pamiętać, że [^a-zA-Z]zastąpi znaki, które nie znajdują się w zakresie znaków AZ / az. Oznacza to, że znaki specjalne podoba é,ß itd. Lub cyrylicą i takie będą usuwane.

Jeśli zamiana tych znaków nie jest pożądana, użyj zamiast tego wstępnie zdefiniowanych klas znaków:

 str.replaceAll("[^\\p{IsAlphabetic}\\p{IsDigit}]", "");

PS: \p{Alnum}nie osiąga tego efektu, działa tak samo jak [A-Za-z0-9].


11
Wielkie dzięki za ten post - był dla mnie bardzo przydatny. Ponadto uważam, że jest to faktyczna odpowiedź na pytanie. Alfabet łaciński nie jest jedynym na świecie!
Mateva

2
W rzeczywistości podany regex potraktuje „^” jako prawidłowy znak, ponieważ tylko pierwsze wystąpienie „^” neguje znaczenie zaznaczenia. [^\\p{IsAlphabetic}\\p{IsDigit}]działa dobrze.
Bogdan Klichuk

1
@JakubTurcovsky docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html definiuje IsAlphabetic i IsDigit jako właściwości binarne. Alpha i Digit to klasy znaków POSIX (tylko US-ASCII). Z wyjątkiem flagi docs.oracle.com/javase/10/docs/api/java/util/regex/… .
Andre Steingress

@AndreSteingress Prawidłowo, powodem {IsDigit}dla mnie nie działa i {Digit}jest to, że próbuję tego na Androidzie. System Android jest UNICODE_CHARACTER_CLASSdomyślnie włączony. Dzięki za odprawę.
Jakub Turcovsky

Jak zezwolić tylko na Alpha, Digit i Emoji?
Robert Goodrick

50
return value.replaceAll("[^A-Za-z0-9 ]", "");

Spowoduje to pozostawienie spacji nietkniętych. Zakładam, że tego właśnie chcesz. W przeciwnym razie usuń spację z wyrażenia regularnego.


21

Możesz także spróbować tego prostszego wyrażenia regularnego:

 str = str.replaceAll("\\P{Alnum}", "");

2
Lub, zachowując białe znaki:str.replaceAll("[^\\p{Alnum}\\s]", "")
Jonik

Lub \\p{Alnum}\\p{Space}.
Membersound

10

Wyrażenia regularne Java nie wymagają umieszczania ukośnika ( /) ani żadnego innego ogranicznika wokół wyrażenia regularnego, w przeciwieństwie do innych języków, takich jak na przykład Perl.


8

Zrobiłem tę metodę tworzenia nazw plików:

public static String safeChar(String input)
{
    char[] allowed = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_".toCharArray();
    char[] charArray = input.toString().toCharArray();
    StringBuilder result = new StringBuilder();
    for (char c : charArray)
    {
        for (char a : allowed)
        {
            if(c==a) result.append(a);
        }
    }
    return result.toString();
}

5
To dość brutalna siła. Regex to sposób na dostosowanie się do sytuacji PO.
Michael Peterson

1
Masz rację, wyrażenie regularne jest lepsze. Ale wtedy regex i ja nie szło mi dobrze.
zneo

Hah, czy ktoś naprawdę dobrze dogaduje się z regex? ;)
Michael Peterson

6

Rozwiązanie:

value.replaceAll("[^A-Za-z0-9]", "")

Wyjaśnienie:

[^abc] Kiedy daszek ^pojawia się jako pierwszy znak w nawiasach kwadratowych, neguje wzór. Ten wzór pasuje do dowolnego znaku oprócz a lub b lub c.

Patrząc na słowo kluczowe jako dwie funkcje:

  • [(Pattern)] = match(Pattern)
  • [^(Pattern)] = notMatch(Pattern)

Ponadto w odniesieniu do wzoru:

  • A-Z = all characters included from A to Z

  • a-z = all characters included from a to z

  • 0=9 = all characters included from 0 to 9

Dlatego zastąpi wszystkie znaki NIE uwzględnione we wzorcu


3

Jeśli chcesz również zezwolić na znaki alfanumeryczne, które nie należą do zestawu znaków ascii, jak na przykład niemiecki umlaut, możesz rozważyć użycie następującego rozwiązania:

 String value = "your value";

 // this could be placed as a static final constant, so the compiling is only done once
 Pattern pattern = Pattern.compile("[^\\w]", Pattern.UNICODE_CHARACTER_CLASS);

 value = pattern.matcher(value).replaceAll("");

Pamiętaj, że użycie flagi UNICODE_CHARACTER_CLASS może mieć wpływ na obniżenie wydajności (patrz javadoc tej flagi)


1

Prosta metoda:

public boolean isBlank(String value) {
    return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
}

public String normalizeOnlyLettersNumbers(String str) {
    if (!isBlank(str)) {
        return str.replaceAll("[^\\p{L}\\p{Nd}]+", "");
    } else {
        return "";
    }
}


1

Za pomocą Guawy można łatwo łączyć różne rodzaje kryteriów. Do konkretnego rozwiązania możesz użyć:

value = CharMatcher.inRange('0', '9')
        .or(CharMatcher.inRange('a', 'z')
        .or(CharMatcher.inRange('A', 'Z'))).retainFrom(value)

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.