Thay thế tất cả các ký tự không chữ và số bằng các chuỗi trống


197

Tôi đã thử sử dụng nhưng không được

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

36
Các bạn, bạn quên có những bảng chữ cái khác với chữ Latinh.
Mateva

2
Nhưng nếu bạn muốn xác thực tên máy chủ chẳng hạn, điều này sẽ tốt để loại trừ các bảng chữ cái không hợp lệ.
Gurnard

Câu trả lời:


245

Sử dụng [^A-Za-z0-9].

Lưu ý: đã xóa khoảng trắng vì đó thường không được coi là chữ và số.


10
Không phải là không gian ở cuối lớp nhân vật.
Andrew Duffy

6
Có lẽ anh ấy đã từng lập trình trong PHP.
William

10
@William - thật không may khi PHP hiện đang nhận được tín dụng cho PCRE
Thomas Dignan

reg exp là ok, chỉ cần xóa "/" khỏi chuỗi regrec khỏi value.replaceAll ("/ [^ A-Za-z0-9] /", ""); đến value.replaceAll ("[^ A-Za-z0-9]", ""); bạn không cần "/" bên trong regrec, tôi nghĩ bạn đã nhầm lẫn với các mẫu javascript
eriknyk

128

Thử

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

hoặc là

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

4
Với dấu gạch dưới,return value.replaceAll("\\W", "");
erickson

Tất nhiên. Trình biên dịch là tuyệt vời để phát hiện ra loại đó.
Andrew Duffy

1
Người thứ hai không trả lời câu hỏi. Còn những nhân vật như: / \ etc thì sao?
Thế chiến.

67

Bạn nên lưu ý rằng [^a-zA-Z]sẽ thay thế các ký tự không nằm trong phạm vi ký tự AZ / az. Điều đó có nghĩa là các ký tự đặc biệt như é, ßv.v. hoặc các ký tự cyrillic và như vậy sẽ bị xóa.

Nếu không muốn thay thế các ký tự này, hãy sử dụng các lớp ký tự được xác định trước thay thế:

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

PS: \p{Alnum}không đạt được hiệu ứng này, nó hoạt động giống như [A-Za-z0-9].


11
Cảm ơn rất nhiều cho bài viết này - nó rất hữu ích cho tôi. Ngoài ra, tôi tin rằng đây là câu trả lời thực sự cho câu hỏi. Bảng chữ cái Latin không phải là duy nhất trên thế giới!
Mateva

2
Trên thực tế, regex đã nêu sẽ coi "^" là một ký tự hợp lệ, vì chỉ lần xuất hiện đầu tiên của "^" là phủ định ý nghĩa của lựa chọn. [^\\p{IsAlphabetic}\\p{IsDigit}]hoạt động tốt
Bogdan Klichuk

1
@JakubTurcovsky docs.oracle.com/javase/10/docs/api/java/util/regex/Potype.html định nghĩa IsAlphabetic và IsDigit là thuộc tính nhị phân. Alpha và Digit là các lớp ký tự POSIX (chỉ US-ASCII). Ngoại trừ docs.oracle.com/javase/10/docs/api/java/util/regex/ Thẻ cờ được chỉ định.
Andre Steingress

@AndreStasingress Đúng, lý do {IsDigit}không phù hợp với tôi và {Digit}tôi đang thử điều này trên Android. Và Android đã được UNICODE_CHARACTER_CLASSbật theo mặc định. Cảm ơn đã giải phóng mặt bằng.
Jakub Turcovsky

Làm cách nào để chỉ cho phép Alpha, Digit và Emoji?
Robert Goodrick

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

Điều này sẽ để lại không gian nguyên vẹn. Tôi cho rằng đó là những gì bạn muốn. Nếu không, loại bỏ không gian từ regex.


21

Bạn cũng có thể thử regex đơn giản hơn này:

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

2
Hoặc, giữ khoảng trắng:str.replaceAll("[^\\p{Alnum}\\s]", "")
Jonik

Hoặc \\p{Alnum}\\p{Space}.
viên

10

Các biểu thức chính quy của Java không yêu cầu bạn đặt dấu gạch chéo ( /) hoặc bất kỳ dấu phân cách nào khác xung quanh biểu thức chính, trái ngược với các ngôn ngữ khác như Perl chẳng hạn.


8

Tôi đã thực hiện phương pháp này để tạo tên tệp:

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
Đây là lực lượng vũ phu. Regex là con đường phù hợp với tình hình của OP.
Michael Peterson

1
Bạn nói đúng, regex tốt hơn. Nhưng tại thời điểm đó, regex và tôi, tôi không hợp nhau.
zneo

Hah, có ai thực sự hòa hợp với regex không? ;)
Michael Peterson

6

Giải pháp:

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

Giải trình:

[^abc] Khi một dấu mũ ^xuất hiện dưới dạng ký tự đầu tiên bên trong dấu ngoặc vuông, nó sẽ phủ nhận mẫu. Mẫu này phù hợp với bất kỳ ký tự nào ngoại trừ a hoặc b hoặc c.

Nhìn vào từ khóa như hai chức năng:

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

Hơn nữa liên quan đến một mô hình:

  • 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

Do đó, nó sẽ thay thế tất cả các char KHÔNG có trong mẫu


3

Nếu bạn cũng muốn cho phép các ký tự chữ và số không thuộc về các ký tự ascii được đặt, ví dụ như tiếng Đức umlaut, bạn có thể xem xét sử dụng giải pháp sau:

 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("");

Xin lưu ý rằng việc sử dụng cờ UNICODE_CHARACTER_CLASS có thể áp dụng hình phạt hiệu suất (xem javadoc của cờ này)


1

Phương pháp đơn giản:

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

Sử dụng ổi bạn có thể dễ dàng kết hợp các loại tiêu chí khác nhau. Đối với giải pháp cụ thể của bạn, bạn có thể sử dụng:

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

1

CharMatcher của Guava cung cấp một giải pháp ngắn gọn:

output = CharMatcher.javaLetterOrDigit().retainFrom(input);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.