Jak usunąć znaki niealfanumeryczne?

349

Muszę usunąć wszystkie znaki z ciągu, który nie jest w a-z A-Z 0-9zestawie lub nie jest spacją.

Czy ktoś ma do tego funkcję?

zuk1
źródło

Odpowiedzi:

695

Wygląda na to, że prawie wiedziałeś już, co chcesz zrobić, w zasadzie zdefiniowałeś to jako wyrażenie regularne.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Chad Birch
źródło
8
zuk1: regexbuddy jest w tym bardzo pomocny
powtórka
2
Oto przykład, jeśli chcesz uwzględnić łącznik jako dozwoloną postać. Potrzebowałem tego, ponieważ musiałem usunąć niedozwolone znaki z nazwy użytkownika Moodle, na podstawie adresów e-mail: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Evan Donovan
2
Czy działałoby to dokładnie tak samo z apostrofami (pojedynczymi cudzysłowami) wokół wyrażenia regularnego, zamiast znaków cudzysłowu (podwójnych cudzysłowów)? Np .:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625
3
Chcemy wyjaśnienia na ten temat :). Ludzie przychodzą tutaj, aby zobaczyć, dlaczego tak jest. Proszę również rozważyć wyjaśnienie Regex! Dzięki
Pratik,
1
Co jeśli chcemy zachować zaakcentowane postacie?
wonzbak
169

W przypadku znaków Unicode jest to:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
voondo
źródło
cześć voondo, co jest z tą rzeczą / ui .. jak to nazywasz? czy ktoś może rzucić mi trochę światła. Dziękuję Ci.
kebyang
4
Dla wyjaśnienia nazywane są flagami. Są one umieszczane za ogranicznikiem zamykającym (w tym przypadku jest to „/”, ale może to być „~” lub „@” lub dowolny znak, którego chcesz użyć, o ile ograniczniki otwierający i zamykający są takie same) i zmienić zachowanie wyrażenia.
Doktor J
1
Btw, \wobejmuje, \da więc nie \djest konieczne. Jest to również błędne, ponieważ pozostawi podkreślenia w wynikowym ciągu (który jest również zawarty w \w).
smatty
2
Nadal występuje w tym błąd, klasy znaków należy zakończyć za pomocą „:]”, więc poprawna linia to: preg_replace („/ [^ [: alnum:] [: space:]] / ui", '', $ string);
h00ligan
4
Czy iflaga jest tu naprawdę konieczna, ponieważ [:alnum:]obejmuje już oba przypadki?
billynoah
50

Wyrażenie regularne jest twoją odpowiedzią.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • iOznacza wielkość liter ma znaczenie.
  • ^ oznacza, że ​​nie zaczyna się.
  • \d pasuje do dowolnej cyfry.
  • a-zdopasowuje wszystkie znaki pomiędzy ai z. Ze względu na iparametr, którego nie musisz określaća-z i A-Z.
  • Po \dspacji, więc spacje są dozwolone w tym wyrażeniu regularnym.
raspi
źródło
3
Chcemy wyjaśnienia na ten temat :). Ludzie przychodzą tutaj, aby zobaczyć, dlaczego tak jest. Proszę również rozważyć wyjaśnienie Regex! Nie wszyscy są wystarczająco zaawansowani, aby wiedzieć, co tam napisałeś bez wyjaśnienia. Dzięki
Pratik,
@PratikCJoshi I oznacza brak rozróżniania wielkości liter. ^ oznacza, że ​​nie zaczyna się od. \ d pasuje do dowolnej cyfry. az dopasowuje wszystkie znaki od a do z. Ze względu na parametr i nie musisz określać az i AZ. Po \ d jest spacja, więc spacje są dozwolone w tym wyrażeniu regularnym.
bart
1
Ludzie nie czytają komentarzy jako odpowiedzi. Zaktualizuj odpowiedź!
Pratik,
18

oto naprawdę prosty regex:

\W|_

i używane tak, jak potrzebujesz (z /ogranicznikiem do przodu ).

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

Przetestuj to tutaj za pomocą tego wspaniałego narzędzia, które wyjaśnia, co robi regex:

http://www.regexr.com/

Alex Stephens
źródło
1
Nadal potrzebujesz /uflagi, w przeciwnym razie usuwane są również litery inne niż ascii.
Xeoncross,
Schludny ale pasujące do spacji, a jeśli jest to pożądane, prawdopodobnie może podwoić wydajność za pomocą klasy postaci i dodatkowego kwantyfikatora dla jednego lub większej liczby [\W_]+
bańka bąbelkowa
18

Jeśli chcesz obsługiwać inne języki zamiast typowego AZ, możesz użyć następujących opcji:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]definiuje negowaną (pasuje do znaku, który nie jest zdefiniowany) klasę znaków:
    • \p{L}: list z dowolnego języka.
    • \p{N}: znak numeryczny w dowolnym skrypcie.
    • : znak spacji.
  • + łapczywie dopasowuje klasę postaci od 1 do nieograniczonej liczby razy.

Pozwoli to zachować litery i cyfry z innych języków i skryptów, a także 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} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Uwaga: To bardzo stare, ale wciąż aktualne pytanie. Odpowiadam wyłącznie w celu dostarczenia dodatkowych informacji, które mogą być przydatne dla przyszłych gości.

Jonathon
źródło
8
[\W_]+

 

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

Zaznacza wszystkie nie AZ, az, 0-9 i usuwa.

Zobacz przykład tutaj: https://regexr.com/3h1rj

Intacto
źródło
1
co to wyrażenie regularne / [\ W _] + / u?
Ângelo Rigo
\Wjest odwrotnością tego, \wktóre są postaciami A-Za-z0-9_. Dopasuje więc \Wkażdą postać, która nie jest, A-Za-z0-9_i usunie je. Jest []to granica zestawu znaków . +Jest zbędny na zbiorze znaków granicy, ale zwykle oznacza 1 lub więcej znaków. uFlag rozszerza wyraz m.in. Unicode wsparcie charakter, co oznacza, że nie usunie znaki poza kodem 255 znaków takich jak ª²³µ. Przykład różnych zastosowań 3v4l.org/hSVV5 ze znakami Unicode i Ascii .
fyrye
2
preg_replace("/\W+/", '', $string)

Możesz to przetestować tutaj: http://regexr.com/

TOZ
źródło
Na odpowiedź @Alex Stevens nie powoduje to podkreślenia „_”.
Ariel Allon
0

Ja też szukałem odpowiedzi i moim zamiarem było wyczyszczenie każdego alfy i nie powinno być więcej niż jedno miejsce.
Więc zmodyfikowałem odpowiedź Alexa na to i to działa na mnie preg_replace('/[^a-z|\s+]+/i', ' ', $name)
Wyrażenie regularne powyżej zmieniło sy8ed sirajul7_islamsię w sy ed sirajul islam
Objaśnienie: regex nie sprawdzi ŻADNEGO od a do z w przypadku niewrażliwego sposobu lub więcej niż jednej białej spacji i zostanie przekonwertowany na pojedynczy przestrzeń.

ssi-anik
źródło
-2

Możesz podzielić ciąg na znaki i przefiltrować.

<?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

?>
zekel
źródło
Powód odrzucenia: 3v4l.org/fqLVZ Ponadto wywoływanie funkcji (3 + N) na łańcuchu o nieznanej długości wydaje się naprawdę nieatrakcyjne w porównaniu z pojedynczym i prostym preg_replace()wywołaniem.
mickmackusa,