Função para retornar apenas caracteres alfanuméricos da string?

98

Estou procurando uma função php que pegará uma string de entrada e retornará uma versão limpa dela removendo todos os caracteres especiais, deixando apenas o alfanumérico.

Preciso de uma segunda função que faça o mesmo, mas retorne apenas caracteres alfabéticos AZ.

Qualquer ajuda muito apreciada.

Scott B
fonte
Em qual formulário de normalização Unicode eles estão e por que você faria isso?
tchrist
1
Quando você diz AZ e 'alfanumérico', você realmente quer dizer apenas AZ ou deseja combinar todas as letras de todos os idiomas, incluindo idiomas estrangeiros e scripts obsoletos?
Mark Byers
Se você está fazendo isso para fazer uma comparação de strings insensível ao acento, está fazendo a coisa errada.
tchrist
3
É não apenas “de todas as línguas”. É inglês. O inglês usa a escrita latina. Existem unichars '\p{Latin}' '\p{Alphabetic}' '[^A-Za-z]' | wc -l== 1192 pontos de código que são alfabéticos latinos, mas que não são AZ. É um mito comum que ASCII seja suficiente para o inglês. Não é, e é por isso que escrever AZ tem um cheiro de código .
tchrist
1
@Scott B: O inglês não usa apenas as 26 letras de AZ. Por exemplo, a palavra currículo inclui é. Talvez você possa explicar o que está tentando fazer, pois isso pode ajudá-lo a obter melhores respostas.
Mark Byers

Respostas:

212

Aviso: Observe que o inglês não se restringe apenas a AZ.

Tente isso para remover tudo, exceto az, AZ e 0-9:

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

Se sua definição de alfanumérico inclui letras em idiomas estrangeiros e scripts obsoletos, você precisará usar as classes de caracteres Unicode.

Tente isso para deixar apenas AZ:

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

O motivo do aviso é que palavras como currículo contêm a letra éque não corresponde a isso. Se você deseja corresponder a uma lista específica de letras, ajuste a expressão regular para incluir essas letras. Se você quiser combinar todas as letras, use as classes de caracteres apropriadas conforme mencionado nos comentários.

Mark Byers
fonte
2
Não, um alfanumérico é [\p{Alphabetic}\p{Numeric}]. Esqueci a propriedade alfabética PCRE, mas você pode fazer uma aproximação com [\pL\pM\pN].
tchrist
1
@tchrist: Suponho que, pelo fato de ele ter mencionado especificamente o AZ, ele apenas deseja corresponder a isso, embora admita que a questão poderia ser muito mais clara neste ponto. Vou pedir um esclarecimento.
Mark Byers
1
@Mark, eu não estava discutindo com a segunda parte de sua resposta, embora se ele não tenha decomposto canonicamente a string primeiro, não funcionará direito. Eu estava discutindo com a primeira parte. Além disso, tento sempre corrigir regexes que funcionam em qualquer dado, não apenas em ASCII velho e mofado. :) Daí o mantra de que deste lado do Millennium, [A-Z]sempre está errado, às vezes .
tchrist
1
@Mark Byers, entendo ... e sim, eu prefiro o, imas sempre tive que me preocupar com a demografia do inglês. Esqueço que muitas pessoas precisam pensar em outras línguas. BTW, acabei de notar que você é o usuário com a maior reputação que nunca fez 1 pergunta. Até Jon Skeet já fez perguntas antes!
JD Isaacks
1
por que há um + no final da regexp? Não seria ... mesmo se você o removesse?
Dennis
2

Em vez disso preg_replace, você sempre pode usar as funções de filtro do PHP usando a filter_var()função com FILTER_SANITIZE_STRING.

Mark Baker
fonte
O PHP tem acesso ao algoritmo ISO Stringprep? Eu sei que Perl e Java fazem.
tchrist
Eu acredito que a função de filtro de string funciona predominantemente com ASCII de 7 bits, mas não me mencione isso.
Mark Baker
30
Por favor, você pode nos dizer uma maneira explícita de fazer o que o usuário está pedindo usando FILTER_SANITIZE_STRING? Pelo que sei, o mais próximo que pode ser arquivado dessa forma é com FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH, mas isso não deixará apenas letras e números, mas também pontos, barras, porcentagens e tudo mais.
Pere de
$ iMycleanVar = filter_var ($ sStringWithNumbers, FILTER_SANITIZE_NUMBER_INT);
Sultanos
4
Parece mais um comentário do que uma resposta. Dê uma explicação adequada ao escrever uma resposta.
Siraj Alam
0
  1. Santize para números [ 0-9 ] e alfabetos em geral [ \ pL ]:
$string = preg_replace("/[^0-9\pL]+/", "", $string)
  1. Santize especificamente para os alfabetos de A a Z (não diferencia maiúsculas de minúsculas) [ a-zA-Z ]:
$string = preg_replace("/[^a-zA-Z]+/", "", $string)
Sky7ure
fonte