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 ]/", "");
Alex Gomes
źródło
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.

Mirek Pluta
źródło
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]|_", "");
Andrew Duffy
źródło
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].

Andre Steingress
źródło
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.

erickson
źródło
21

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

 str = str.replaceAll("\\P{Alnum}", "");
saurav
źródło
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.

abyx
źródło
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();
}
zneo
źródło
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

GalloCedrone
źródło
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)

kłapnięcie
źródło
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 "";
    }
}
Alberto Cerqueira
źródło
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)
Deb
źródło
1

CharMatcher firmy Guava zapewnia zwięzłe rozwiązanie:

output = CharMatcher.javaLetterOrDigit().retainFrom(input);
Bunarro
źródło