Làm thế nào để loại bỏ các ký tự không chữ và số?


349

Tôi cần xóa tất cả các ký tự khỏi một chuỗi không có trong a-z A-Z 0-9 được đặt hoặc không phải là khoảng trắng.

Có ai có một chức năng để làm điều này?

Câu trả lời:


695

Âm thanh như bạn gần như đã biết những gì bạn muốn làm, về cơ bản bạn đã định nghĩa nó là một regex.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);

8
zuk1: regexbuddy là một trợ giúp tuyệt vời với điều đó
tái hiện

2
Dưới đây là một ví dụ nếu bạn muốn bao gồm dấu gạch nối dưới dạng ký tự được phép. Tôi cần điều này bởi vì tôi cần loại bỏ các ký tự không được phép khỏi tên người dùng Moodle, dựa trên địa chỉ email: preg numplace ("/ [^ a-z0-9 _. @ \ -] /", '', $ chuỗi);
Evan Donovan

2
Điều này có hoạt động chính xác như vậy với dấu nháy đơn (dấu ngoặc đơn) xung quanh biểu thức chính quy, thay vì dấu ngoặc kép (dấu ngoặc kép) không? Ví dụ:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625

3
Chúng tôi muốn giải thích về điều này :). Mọi người đến đây để xem tại sao nó là như vậy. Hãy xem xét giải thích Regex quá! Cảm ơn
Pratik

1
Điều gì nếu chúng ta muốn giữ các nhân vật có dấu?
wonzbak

169

Đối với các ký tự unicode, đó là:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);

chào voondo, những gì với / ui điều .. bạn gọi nó là gì? bất cứ ai có thể xin vui lòng làm sáng tỏ tôi. Cảm ơn bạn.
kebyang

4
Để làm rõ, chúng được gọi là cờ. Chúng được đặt sau dấu phân cách đóng (trong trường hợp này là "/", nhưng nó có thể là "~" hoặc "@" hoặc bất kỳ ký tự nào bạn muốn sử dụng miễn là các dấu phân cách mở và đóng giống nhau) và thay đổi hành vi của biểu thức.
Doktor J

1
Btw, \wbao gồm \dvà do đó \dlà không cần thiết. Ngoài ra, điều này là sai bởi vì nó cũng sẽ để lại dấu gạch dưới trong chuỗi kết quả (cũng được bao gồm trong \w).
smathy

2
Vẫn còn một lỗi trong đó, các lớp ký tự cần được chấm dứt bằng ':]', vì vậy dòng chính xác sẽ là: preg numplace ("/ [^ [: alnum:] [: space:]] / ui", '', $ chuỗi);
h00ligan

4
icờ thực sự cần thiết ở đây vì [:alnum:]đã bao gồm cả hai trường hợp?
billynoah

50

Biểu hiện thường xuyên là câu trả lời của bạn.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • Các iviết tắt cho trường hợp không nhạy cảm.
  • ^ có nghĩa là, không bắt đầu với.
  • \d phù hợp với bất kỳ chữ số.
  • a-zphù hợp với tất cả các nhân vật giữa az. Do itham số bạn không phải chỉ định a-zA-Z.
  • Sau khi \dcó một khoảng trắng, vì vậy các khoảng trắng được cho phép trong biểu thức chính quy này.

3
Chúng tôi muốn giải thích về điều này :). Mọi người đến đây để xem tại sao nó là như vậy. Hãy xem xét giải thích Regex quá! Không phải ai cũng đủ tiến bộ để biết những gì bạn đã viết ở đó mà không cần giải thích. Cảm ơn
Pratik

@PratikCJoshi Chữ i là viết tắt của trường hợp không nhạy cảm. ^ có nghĩa là, không bắt đầu với. \ d khớp với bất kỳ chữ số nào. az khớp với tất cả các ký tự giữa a và z. Do tham số i, bạn không phải chỉ định az và AZ. Sau \ d có một khoảng trắng, vì vậy khoảng trắng được cho phép trong biểu thức chính quy này.
bart

1
Mọi người không đọc bình luận như câu trả lời. Hãy cập nhật câu trả lời!
Pratik

18

Đây là một regex thực sự đơn giản cho điều đó:

\W|_

và được sử dụng khi bạn cần nó (với /dấu phân cách dấu gạch chéo về phía trước ).

preg_replace("/\W|_/", '', $string);

Kiểm tra nó ở đây với công cụ tuyệt vời này giải thích những gì regex đang làm:

http://www.regexr.com/


1
Bạn vẫn cần /ucờ nếu không các chữ cái không phải ascii cũng bị xóa.
Xeoncross

Gọn gàng nhưng cũng phù hợp với không gian và nếu điều này là muốn, có thể có thể tăng gấp đôi hiệu suất bằng cách sử dụng lớp nhân vật và bộ định lượng bổ sung cho một hoặc nhiều [\W_]+
bong bóng bobble

18

Nếu bạn cần hỗ trợ các ngôn ngữ khác, thay vì AZ thông thường, bạn có thể sử dụng các ngôn ngữ sau:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]định nghĩa một lớp ký tự phủ định (Nó sẽ khớp với một ký tự không được xác định) của lớp:
    • \p{L}: một lá thư từ bất kỳ ngôn ngữ.
    • \p{N}: một ký tự số trong bất kỳ tập lệnh nào .
    • : một nhân vật không gian.
  • + tham lam phù hợp với lớp nhân vật từ 1 đến không giới hạn .

Điều này sẽ bảo vệ các chữ cái và số từ các ngôn ngữ và tập lệnh khác cũng như AZ:

preg_replace('/[^\p{L}\p{N} ]+/', '', 'hello-world'); // helloworld
preg_replace('/[^\p{L}\p{N} ]+/', '', 'abc@~#123-+=öäå'); // abc123öäå
preg_replace('/[^\p{L}\p{N} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Lưu ý: Đây là một câu hỏi rất cũ, nhưng vẫn có liên quan. Tôi đang trả lời hoàn toàn để cung cấp thông tin bổ sung có thể hữu ích cho khách truy cập trong tương lai.


8
[\W_]+

 

$string = preg_replace("/[\W_]+/u", '', $string);

Nó chọn tất cả không phải AZ, az, 0-9 và xóa nó.

Xem ví dụ tại đây: https://regexr.com/3h1rj


1
regex này / [\ W _] + / u nghĩa là gì?
Ângelo Rigo

\Wlà nghịch đảo trong \wđó là các ký tự A-Za-z0-9_. Vì vậy, \Wsẽ phù hợp với bất kỳ nhân vật không phải là A-Za-z0-9_và loại bỏ chúng. Đây []là một ranh giới thiết lập nhân vật . Cái +thừa là trên một ranh giới tập ký tự nhưng thông thường có nghĩa là 1 hoặc nhiều ký tự. Các ucờ mở rộng khái niệm bao gồm hỗ trợ ký tự unicode, có nghĩa là nó sẽ không loại bỏ ký tự vượt quá 255 ký tự mã như ª²³µ. Ví dụ về các cách sử dụng khác nhau 3v4l.org/hSVV5 với các ký tự unicode và ascii.
fyrye

2
preg_replace("/\W+/", '', $string)

Bạn có thể kiểm tra nó ở đây: http://regexr.com/


Theo câu trả lời của @Alex Stevens, điều này không bắt được dấu gạch dưới "_".
Ariel Allon

0

Tôi cũng đang tìm câu trả lời và ý định của tôi là dọn sạch mọi phi alpha và không nên có nhiều hơn một không gian.
Vì vậy, tôi đã sửa đổi câu trả lời của Alex cho vấn đề này và điều này có hiệu quả với tôi preg_replace('/[^a-z|\s+]+/i', ' ', $name)
. Regex ở trên đã chuyển sy8ed sirajul7_islamsang sy ed sirajul islam
Giải thích: regex sẽ kiểm tra KHÔNG BẤT K from từ a đến z trong trường hợp không nhạy cảm hoặc nhiều hơn một khoảng trắng và nó sẽ được chuyển đổi thành một không gian.


-2

Bạn có thể chia chuỗi thành các ký tự và lọc nó.

<?php 

function filter_alphanum($string) {
    $characters = str_split($string);
    $alphaNumeric = array_filter($characters,"ctype_alnum");
    return join($alphaNumeric);
}

$res = filter_alphanum("a!bc!#123");
print_r($res); // abc123

?>

Lý do cho downvote: 3v4l.org/fqLVZ Các hàm gọi (3 + N) trên một chuỗi có độ dài không xác định dường như thực sự không hấp dẫn so với một preg_replace()cuộc gọi đơn giản và đơn giản .
mickmackusa
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.