Como remover caracteres não alfanuméricos?

349

Preciso remover todos os caracteres de uma sequência que não esteja no a-z A-Z 0-9conjunto ou não seja espaços.

Alguém tem uma função para fazer isso?

zuk1
fonte

Respostas:

695

Parece que você quase sabia o que queria fazer, basicamente o definiu como um regex.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Chad Birch
fonte
8
zuk1: RegexBuddy é uma grande ajuda com isso
relipse
2
Aqui está um exemplo se você deseja incluir o hífen como caractere permitido. Eu precisava disso porque precisava remover caracteres não permitidos de um nome de usuário do Moodle, com base nos endereços de email: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Evan Donovan
2
Isso funcionaria exatamente da mesma forma com apóstrofos (aspas simples) ao redor da expressão regular, em vez de aspas (aspas duplas)? Por exemplo:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625
3
Queremos explicações sobre isso :). As pessoas vêm aqui para ver Por que é assim que é. Por favor, considere a explicação Regex também! Obrigado
Pratik
11
E se quisermos manter os caracteres acentuados?
wonzbak 23/06
169

Para caracteres unicode, é:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
voondo
fonte
oi voondo, o que há com a coisa / ui .. como você chama? Alguém pode me dar alguma luz? Obrigado.
kebyang
4
Para esclarecimento, eles são chamados de sinalizadores. Eles são colocados após o delimitador de fechamento (neste caso, é "/", mas pode ser "~" ou "@" ou qualquer caractere que você deseja usar, desde que os delimitadores de abertura e fechamento sejam os mesmos) e altere o comportamento da expressão.
Doktor J
11
Entre, \winclui \de assim o \dé desnecessário. Além disso, isso está errado porque também deixará sublinhados na string resultante (que também está incluída em \w).
smathy
2
Ainda há um erro nisso, as classes de caracteres precisam ser terminadas com ':]' para que a linha correta seja: preg_replace ("/ [^ [: alnum:] [: space:]] / ui", '', $ string);
h00ligan
4
A ibandeira é realmente necessária aqui, já que [:alnum:]já abrange os dois casos?
Billynoah 25/09/2015
50

Expressão regular é a sua resposta.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • O isignificado de maiúsculas e minúsculas.
  • ^ significa, não começa com.
  • \d corresponde a qualquer dígito.
  • a-zcorresponde a todos os caracteres entre ae z. Por causa do iparâmetro, você não precisa especificar a-ze A-Z.
  • Depois de \dhaver um espaço, os espaços são permitidos nesse regex.
raspi
fonte
3
Queremos explicações sobre isso :). As pessoas vêm aqui para ver Por que é assim que é. Por favor, considere a explicação Regex também! Nem todo mundo é avançado o suficiente para saber o que você escreveu lá sem explicação. Obrigado
Pratik
@PratikCJoshi Oi significa maiúsculas e minúsculas. ^ significa que não começa com. \ d corresponde a qualquer dígito. az corresponde a todos os caracteres entre a e z. Por causa do parâmetro i, você não precisa especificar az e AZ. Depois de \ d haver um espaço, os espaços são permitidos nesse regex.
Bart
11
As pessoas não leem comentários como resposta. Atualize a resposta!
Pratik
18

aqui está um regex realmente simples para isso:

\W|_

e usado conforme necessário (com um /delimitador de barra).

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

Teste aqui com esta ótima ferramenta que explica o que a regex está fazendo:

http://www.regexr.com/

Alex Stephens
fonte
11
Você ainda precisa da /ubandeira, caso contrário, as letras não-ascii também serão removidas.
Xeoncross
Neat , mas também iria coincidir com os espaços e se este é procurado, provavelmente poderia dobrar o desempenho pelo uso de uma classe de personagem e adicional quantificador para uma ou mais [\W_]+
Bubble Bobble
18

Se você precisar oferecer suporte a outros idiomas, em vez do AZ típico, use o seguinte:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]define uma classe de caracteres negada (corresponderá a um caractere que não está definido) de:
    • \p{L}: uma carta de qualquer idioma.
    • \p{N}: um caractere numérico em qualquer script.
    • : um caractere de espaço.
  • + avidamente corresponde à classe de personagem entre 1 e vezes ilimitadas .

Isso preservará letras e números de outros idiomas e scripts, além do 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} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Nota: Essa é uma pergunta muito antiga, mas ainda relevante. Estou respondendo apenas para fornecer informações adicionais que possam ser úteis para futuros visitantes.

Jonathon
fonte
8
[\W_]+

 

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

Ele seleciona nem todos AZ, az, 0-9 e o exclui.

Veja o exemplo aqui: https://regexr.com/3h1rj

Intacto
fonte
11
o que significa este regex / [\ W _] + / u?
Ângelo Rigo
\Wé o inverso dos \wquais são caracteres A-Za-z0-9_. Portanto \W, corresponderá a qualquer caractere que não seja A-Za-z0-9_e os removerá. O []é um limite do conjunto de caracteres . A +é redundante em um limite de conjunto de caracteres, mas normalmente significa 1 ou mais caracteres. O usinalizador expande a expressão para incluir suporte a caracteres unicode, o que significa que não removerá caracteres além do código de caracteres 255, como ª²³µ. Exemplo de vários usos 3v4l.org/hSVV5 com caracteres unicode e ascii.
fyrye
2
preg_replace("/\W+/", '', $string)

Você pode testá-lo aqui: http://regexr.com/

TOZ
fonte
Pela resposta do @Alex Stevens, isso não captura os sublinhados "_".
Ariel Allon
0

Eu também estava procurando a resposta e minha intenção era limpar todos os não-alfa e não deveria haver mais de um espaço.
Então, eu modifiquei a resposta de Alex para isso, e isso está funcionando para mim preg_replace('/[^a-z|\s+]+/i', ' ', $name)
O regex acima virou sy8ed sirajul7_islampara sy ed sirajul islam
Explicação: regex irá verificar Não é qualquer de A a Z no caso insensível maneira ou de mais de um espaços em branco, e ele será convertido em um único espaço.

ssi-anik
fonte
-2

Você pode dividir a sequência em caracteres e filtrá-la.

<?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
fonte
Motivo para voto negativo : 3v4l.org/fqLVZ Além disso, as funções de chamada (3 + N) em uma sequência de tamanho desconhecido parecem realmente pouco atraentes em comparação com uma preg_replace()chamada simples e simples .
Mckmackusa 17/09/19