Funkcja zwracająca tylko znaki alfanumeryczne z ciągu?

100

Szukam funkcji php, która pobierze ciąg wejściowy i zwróci jego oczyszczoną wersję, usuwając wszystkie znaki specjalne, pozostawiając tylko alfanumeryczne.

Potrzebuję drugiej funkcji, która robi to samo, ale zwraca tylko znaki alfabetu AZ.

Każda pomoc bardzo doceniona.

Scott B.
źródło
W którym formularzu normalizacji Unicode się znajdują i dlaczego miałbyś to zrobić?
tchrist
1
Kiedy mówisz AZ i „alfanumeryczne”, czy naprawdę masz na myśli tylko AZ, czy też chcesz dopasować wszystkie litery ze wszystkich języków, w tym języków obcych i przestarzałych skryptów?
Mark Byers
Jeśli robisz to, aby móc porównać ciągi znaków niewrażliwe na akcent, robisz źle.
tchrist
3
To nie tylko „ze wszystkich języków”. To angielski. Angielski używa alfabetu łacińskiego. Istnieją unichars '\p{Latin}' '\p{Alphabetic}' '[^A-Za-z]' | wc -l== 1192 punkty kodowe, które są alfabetem łacińskim, ale nie są AZ. Powszechnie uważa się, że ASCII jest wystarczające dla języka angielskiego. Tak nie jest i dlatego pisanie AZ ma w sobie zapach kodu .
tchrist
1
@Scott B: Angielski nie używa tylko 26 liter od AZ. Na przykład słowo życiorys zawiera é. Być może mógłbyś wyjaśnić, co próbujesz zrobić, ponieważ może to pomóc w uzyskaniu lepszych odpowiedzi.
Mark Byers,

Odpowiedzi:

215

Ostrzeżenie: pamiętaj, że język angielski nie jest ograniczony tylko do AZ.

Spróbuj tego, aby usunąć wszystko oprócz az, AZ i 0-9:

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

Jeśli Twoja definicja alfanumerycznego obejmuje litery w językach obcych i przestarzałe skrypty, będziesz musiał użyć klas znaków Unicode.

Spróbuj tego, aby zostawić tylko AZ:

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

Powodem ostrzeżenia jest to, że słowa takie jak życiorys zawierają literę é, która nie będzie pasować. Jeśli chcesz dopasować określoną listę liter, dostosuj wyrażenie regularne, aby zawierało te litery. Jeśli chcesz dopasować wszystkie litery, użyj odpowiednich klas znaków, jak wspomniano w komentarzach.

Mark Byers
źródło
2
Nie, jest alfanumeryczny [\p{Alphabetic}\p{Numeric}]. Zapomniałem o właściwości alfabetu PCRE, ale można ją przybliżyć [\pL\pM\pN].
tchrist
1
@tchrist: Zakładam, że ponieważ konkretnie wspomniał AZ, chce tylko dopasować to, chociaż przyznaję, że pytanie mogłoby być o wiele bardziej jasne w tej kwestii. Poproszę o wyjaśnienie.
Mark Byers
1
@Mark, nie kłóciłem się z drugą częścią twojej odpowiedzi, chociaż jeśli najpierw nie rozłożył ciągu kanonicznie, to nie zadziała poprawnie. Kłóciłem się z pierwszą częścią. Staram się również zawsze poprawiać wyrażenia regularne, które działają na dowolnych danych, a nie tylko na spleśniałym starym ASCII. :) Stąd mantra, że ta strona Tysiąclecia [A-Z]jest czasami błędna .
tchrist
1
@Mark Byers, rozumiem ... i tak, wolę, iale zawsze muszę się tylko martwić o angielską grupę demograficzną ... Zapomniałem, że wielu ludzi musi myśleć o innych językach. BTW Właśnie zauważyłem, że jesteś najczęściej reprezentowanym użytkownikiem, który nigdy nie zadał 1 pytania. Nawet Jon Skeet zadawał już pytania!
JD Isaacks
1
dlaczego na końcu wyrażenia regularnego znajduje się znak +? Czy nie byłoby ... tak samo, gdybyś to usunął?
Dennis
2

Zamiast tego preg_replacezawsze możesz użyć funkcji filtrujących PHP, używając filter_var()funkcji with FILTER_SANITIZE_STRING.

Mark Baker
źródło
Czy PHP ma dostęp do algorytmu ISO Stringprep? Wiem, że Perl i Java tak.
tchrist
Uważam, że funkcja filtru tekstowego działa głównie z 7-bitowym ASCII, ale nie cytuj mnie na ten temat.
Mark Baker
30
Czy możesz nam powiedzieć, w jaki sposób będziemy robić to, o co prosi użytkownik FILTER_SANITIZE_STRING? O ile mi wiadomo, najbliższe archiwizowanie w ten sposób to z FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH, ale to nie pozostawia tylko liter i cyfr, ale także kropek, ukośników, procentów i tak dalej.
Pere,
$ iMycleanVar = filter_var ($ sStringWithNumbers, FILTER_SANITIZE_NUMBER_INT);
Sultanos
4
Bardziej przypomina komentarz niż odpowiedź. Podczas pisania odpowiedzi podaj właściwe wyjaśnienie.
Siraj Alam
0
  1. Santize dla liczb [ 0–9 ] i ogólnie alfabetów [ \ pL ]:
$string = preg_replace("/[^0-9\pL]+/", "", $string)
  1. Santize specjalnie dla alfabetów od A do Z (bez rozróżniania wielkości liter) [ a-zA-Z ]:
$string = preg_replace("/[^a-zA-Z]+/", "", $string)
Sky7ure
źródło