ฟังก์ชันที่จะส่งคืนเฉพาะอักขระที่เป็นตัวอักษรและตัวเลขจากสตริง?


102

ฉันกำลังมองหาฟังก์ชัน php ที่จะรับสตริงอินพุตและส่งคืนเวอร์ชันที่ผ่านการฆ่าเชื้อแล้วโดยการลบอักขระพิเศษทั้งหมดออกให้เหลือเพียงตัวอักษรและตัวเลข

ฉันต้องการฟังก์ชันที่สองที่ทำเหมือนกัน แต่ส่งกลับเฉพาะอักขระที่เป็นตัวอักษร AZ

ความช่วยเหลือใด ๆ ที่ชื่นชมมาก


Unicode Normalization Form เหล่านี้อยู่ในรูปแบบใดและทำไมคุณถึงต้องการทำสิ่งนี้
tchrist

1
เมื่อคุณพูด AZ และ 'ตัวอักษรและตัวเลข' คุณหมายถึงเฉพาะ AZ จริง ๆ หรือคุณต้องการจับคู่ตัวอักษรทั้งหมดจากทุกภาษารวมถึงภาษาต่างประเทศและสคริปต์ที่ล้าสมัย
Mark Byers

หากคุณทำเช่นนี้เพื่อให้สามารถเปรียบเทียบสตริงที่ไม่เน้นเสียงได้แสดงว่าคุณกำลังทำสิ่งที่ผิด
tchrist

3
มันไม่ได้เป็นเพียงแค่“จากทั่วทุกภาษา” เป็นภาษาอังกฤษ ภาษาอังกฤษใช้อักษรละติน มีunichars '\p{Latin}' '\p{Alphabetic}' '[^A-Za-z]' | wc -lจุดรหัส == 1192 ที่เป็นอักษรละติน แต่ไม่ใช่ AZ เป็นตำนานที่ถือกันโดยทั่วไปว่า ASCII เพียงพอสำหรับภาษาอังกฤษ มันไม่ได้และนั่นเป็นเหตุผลที่เขียนอาริโซน่ามีกลิ่นรหัสไป
tchrist

1
@Scott B: ภาษาอังกฤษไม่ได้ใช้แค่ 26 ตัวอักษรจาก AZ ตัวอย่างเช่นคำว่าrésuméรวมถึงé บางทีคุณอาจอธิบายสิ่งที่คุณพยายามทำเพราะอาจช่วยให้คุณได้รับคำตอบที่ดีขึ้น
Mark Byers

คำตอบ:


221

คำเตือน: โปรดทราบว่าภาษาอังกฤษไม่ได้ จำกัด เฉพาะ AZ

ลองสิ่งนี้เพื่อลบทุกอย่างยกเว้น az, AZ และ 0-9:

$result = preg_replace("/[^a-zA-Z0-9]+/", "", $s);

หากคำจำกัดความของตัวอักษรและตัวเลขของคุณมีตัวอักษรในภาษาต่างประเทศและสคริปต์ที่ล้าสมัยคุณจะต้องใช้คลาสอักขระ Unicode

ลองสิ่งนี้เพื่อให้เหลือเฉพาะ AZ:

$result = preg_replace("/[^A-Z]+/", "", $s);

เหตุผลในการเตือนคือคำเช่นประวัติมีตัวอักษรéที่ไม่ตรงตามนี้ หากคุณต้องการจับคู่รายการตัวอักษรเฉพาะให้ปรับนิพจน์ทั่วไปเพื่อรวมตัวอักษรเหล่านั้น หากคุณต้องการจับคู่ตัวอักษรทั้งหมดให้ใช้คลาสอักขระที่เหมาะสมตามที่ระบุไว้ในความคิดเห็น


2
[\p{Alphabetic}\p{Numeric}]ไม่เป็นตัวอักษรและตัวเลขเป็น ฉันลืม PCRE คุณสมบัติตามตัวอักษร [\pL\pM\pN]แต่คุณสามารถใกล้เคียงกับมันด้วย
tchrist

1
@tchrist: ฉันคิดว่าเพราะเขาพูดถึง AZ โดยเฉพาะว่าเขาต้องการจับคู่สิ่งนั้นเท่านั้นแม้ว่าฉันจะยอมรับว่าคำถามอาจชัดเจนกว่าในประเด็นนี้ ฉันจะขอคำชี้แจง
Mark Byers

1
@ มาร์คฉันไม่ได้เถียงกับส่วนที่สองของคำตอบของคุณแม้ว่าเขาจะไม่ได้ย่อยสลายสตริงตามบัญญัติก่อนก็ตาม ผมเถียงกับภาคแรก นอกจากนี้ฉันพยายามทำให้ regexes ถูกต้องเสมอที่ทำงานกับข้อมูลใด ๆไม่ใช่เฉพาะกับ ASCII เก่าที่ขึ้นรา :) ดังนั้นมนต์ที่ด้านข้างของมิลเลนเนียมนี้[A-Z]เป็นสิ่งที่ผิดเสมอบางครั้ง
tchrist

1
@ Mark Byers ฉันเห็น .. และใช่ฉันชอบiแต่ฉันเคยมี แต่จะต้องกังวลเกี่ยวกับข้อมูลประชากรภาษาอังกฤษ .. ฉันลืมไปว่าหลายคนต้องคิดถึงภาษาอื่น ๆ BTW ฉันเพิ่งสังเกตว่าคุณเป็นผู้ใช้ที่มีตัวแทนสูงสุดที่ไม่เคยถามคำถาม 1 ข้อ แม้แต่ Jon Skeet ยังเคยถามคำถามมาก่อน!
JD Isaacks

1
เหตุใดจึงมีเครื่องหมาย + ที่ท้าย regexp จะไม่ ... เหมือนกันถ้าคุณลบออก?
Dennis

2

แทนที่จะpreg_replaceใช้ฟังก์ชันตัวกรองของ PHPโดยใช้filter_var()ฟังก์ชันกับFILTER_SANITIZE_STRING.


PHP สามารถเข้าถึงอัลกอริทึม ISO Stringprep ได้หรือไม่ ฉันรู้ว่า Perl และ Java ทำ
tchrist

ฉันเชื่อว่าฟังก์ชันตัวกรองสตริงทำงานได้ดีกับ ASCII 7 บิต แต่อย่าอ้างฉันในเรื่องนั้น
Mark Baker

31
โปรดช่วยบอกวิธีที่ชัดเจนในการทำสิ่งที่ผู้ใช้ขอโดยใช้FILTER_SANITIZE_STRING? สำหรับความรู้ของฉันสิ่งที่ใกล้เคียงที่สุดที่สามารถจัดเก็บได้ด้วยวิธีนี้คือFILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGHแต่นั่นจะไม่เหลือเพียงแค่ตัวอักษรและตัวเลข แต่ยังรวมถึงจุดเครื่องหมายทับเปอร์เซ็นต์และทั้งหมดนั้นด้วย
Pere

5
ดูเหมือนความคิดเห็นมากกว่าคำตอบ ให้คำอธิบายที่เหมาะสมขณะเขียนคำตอบ
Siraj Alam

1
ฉันไม่เชื่อว่ามี FILTER_SANITIZE เป็นตัวเลขและตัวอักษรอยู่จริงอยู่ที่นั่น การละเว้นที่สำคัญทีเดียว
Kzqai

0
  1. Santize สำหรับตัวเลข [ 0-9 ] และตัวอักษรโดยทั่วไป [ \ pL ]:
$string = preg_replace("/[^0-9\pL]+/", "", $string)
  1. Santize โดยเฉพาะสำหรับตัวอักษร A ถึง Z (ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่) [ a-zA-Z ]:
$string = preg_replace("/[^a-zA-Z]+/", "", $string)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.