Considerar:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Suponha que eu tenha o código acima, qual é a maneira correta de escrever a declaração if ($a contains 'are')
?
Você pode usar a strpos()
função usada para encontrar a ocorrência de uma string dentro de outra:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Observe que o uso de !== false
é deliberado ( != false
nem === true
retornará o resultado desejado); strpos()
retorna o deslocamento no qual a corda da agulha começa na corda do palheiro ou o booleano false
se a agulha não for encontrada. Como 0 é um deslocamento válido e 0 é "falsey", não podemos usar construções mais simples como !strpos($a, 'are')
.
strpos($a, 'are') > -1
para testar se é verdade. Do ponto de vista da depuração, acho que meu cérebro gasta menos ciclos de relógio determinando se a linha foi escrita corretamente quando não preciso contar sinais de igual contíguos.Você pode usar expressões regulares; é melhor para a correspondência de palavras, em comparação com
strpos
as mencionadas por outros usuários, e também retornará verdadeiro para strings como tarifa, assistência, olhar, etc. Isso pode ser simplesmente evitado na expressão regular usando limites de palavras.Uma correspondência simples para are pode ser algo como isto:
No lado do desempenho,
strpos
é cerca de três vezes mais rápido e, quando eu fiz um milhão de comparações de uma só vez, foram necessáriospreg_match
1,5 segundos para terminar estrpos
0,5 segundos.Editar: para pesquisar qualquer parte da string, não apenas palavra por palavra, eu recomendaria o uso de uma expressão regular como
A
i
expressão no final da expressão regular altera a expressão regular para não diferenciar maiúsculas de minúsculas. Se você não quiser, pode deixar de fora.Agora, isso pode ser bastante problemático em alguns casos, já que a string de pesquisa $ não é higienizada de qualquer forma, ou seja, pode não passar na verificação em alguns casos, como se
$search
fosse uma entrada do usuário, eles podem adicionar uma string que possa se comportar como alguma expressão regular diferente ...Além disso, aqui está uma ótima ferramenta para testar e ver explicações de várias expressões regulares Regex101
Para combinar os dois conjuntos de funcionalidades em uma única função multiuso (inclusive com distinção entre maiúsculas e minúsculas), você pode usar algo como isto:
fonte
Aqui está uma pequena função utilitária que é útil em situações como esta
fonte
if ($email->contains("@") && $email->endsWith(".com)) { ...
ouif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Embora a maioria dessas respostas diga se uma subcadeia aparece na sua string, geralmente não é o que você deseja se estiver procurando por uma palavra específica e não uma subcadeia .
Qual é a diferença? Substrings podem aparecer em outras palavras:
Uma maneira de atenuar isso seria usar uma expressão regular associada aos limites da palavra (
\b
):Esse método não possui os mesmos falsos positivos observados acima, mas possui alguns casos extremos próprios. Limites de palavra corresponder em caracteres não-palavra (
\W
), que vão ser qualquer coisa que não éa-z
,A-Z
,0-9
, ou_
. Isso significa que dígitos e sublinhados serão contados como caracteres de palavras e cenários como este falharão:Se você quiser algo mais preciso do que isso, terá que começar a analisar a sintaxe no idioma inglês, e essa é uma grande lata de worms (e assume o uso adequado da sintaxe, de qualquer maneira, o que nem sempre é um dado).
fonte
\b
partidas duas coisas que\W
não, o que torna grande para encontrar palavras em uma string: Combina início da string (^
) e no final da string ($
)Para determinar se uma string contém outra, você pode usar a função PHP strpos () .
int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )
CUIDADO:
Se a agulha que você está procurando estiver no início do palheiro, ela retornará à posição 0; se você fizer uma
==
comparação que não funcione, será necessário fazer uma===
Um
==
sinal é uma comparação e testa se a variável / expressão / constante à esquerda tem o mesmo valor que a variável / expressão / constante à direita.Um
===
sinal é uma comparação para ver se duas variáveis / expressões / constantes são iguaisAND
têm o mesmo tipo - ou seja, ambas são strings ou ambas são números inteiros.fonte
Veja
strpos()
:fonte
Usar
strstr()
oustristr()
se sua pesquisa não diferencia maiúsculas de minúsculas seria outra opção.fonte
strstr($a, 'are')
é muito mais elegante que o feiostrpos($a, 'are') !== false
. PHP realmente precisa de umastr_contains()
função.Utilize a correspondência sem distinção entre maiúsculas e minúsculas usando
stripos()
:fonte
Veja os comentários de SamGoody e Lego Stormtroopr.
Se você está procurando um algoritmo PHP para classificar os resultados da pesquisa com base na proximidade / relevância de várias palavras, aqui é uma maneira rápida e fácil de gerar resultados de pesquisa apenas com o PHP:
Problemas com os outros métodos boolean busca tais como
strpos()
,preg_match()
,strstr()
oustristr()
Método PHP baseado no Vector Space Model e tf-idf (termo frequência - frequência inversa do documento):
Parece difícil, mas é surpreendentemente fácil.
Se queremos procurar várias palavras em uma string, o problema principal é como atribuímos um peso a cada uma delas?
Se pudéssemos ponderar os termos em uma string com base em quão representativos eles são da string como um todo, poderíamos ordenar nossos resultados pelos que melhor corresponderem à consulta.
Esta é a idéia do modelo de espaço vetorial, não muito longe de como a pesquisa de texto completo do SQL funciona:
CASO 1
RESULTADO
CASO 2
RESULTADOS
CASO 3
RESULTADOS
Há uma abundância de melhorias a serem feitas, mas o modelo fornece uma maneira de obter bons resultados de consultas naturais, que não têm operadores booleanos tais como
strpos()
,preg_match()
,strstr()
oustristr()
.NOTA BENE
Opcionalmente, eliminando a redundância antes de pesquisar as palavras
reduzindo assim o tamanho do índice e resultando em menos requisitos de armazenamento
menos E / S de disco
indexação mais rápida e, consequentemente, uma pesquisa mais rápida.
1. Normalização
2. Eliminação de palavras-chave
3. Substituição de dicionário
Substitua as palavras por outras que tenham um significado idêntico ou semelhante. (ex: substitua instâncias de 'fome' e 'fome' por 'fome')
Outras medidas algorítmicas (bola de neve) podem ser realizadas para reduzir ainda mais as palavras ao seu significado essencial.
A substituição de nomes de cores por seus equivalentes hexadecimais
A redução dos valores numéricos, reduzindo a precisão, são outras maneiras de normalizar o texto.
RECURSOS
fonte
Se você deseja evitar o problema "falsey" e "truth", pode usar substr_count:
É um pouco mais lento que o strpos, mas evita os problemas de comparação.
fonte
false
para "você tem certeza?" desde a posição parastrpos
é0
Outra opção é usar a função strstr () . Algo como:
Ponto a observar: A função strstr () faz distinção entre maiúsculas e minúsculas. Para uma pesquisa que não diferencia maiúsculas de minúsculas, use a função stristr () .
fonte
fonte
WARNING preg_match(): Delimiter must not be alphanumeric or backslash
Estou um pouco impressionado que nenhuma das respostas aqui que usou
strpos
,strstr
e funções similares mencionado Funções Multibyte corda ainda (2015/05/08).Basicamente, se estiver com problemas para encontrar palavras com caracteres específicos para alguns idiomas , como alemão, francês, português, espanhol etc. (por exemplo: ä , é , ô , ç , º , ñ ), convém preceder as funções com
mb_
. Portanto, a resposta aceita usariamb_strpos
oumb_stripos
(para correspondência sem distinção entre maiúsculas e minúsculas):Se você não pode garantir que todos os seus dados sejam 100% em UTF-8 , convém usar as
mb_
funções.Um bom artigo para entender por que é o Absoluto Mínimo Todo desenvolvedor de software deve saber absolutamente, positivamente sobre Unicode e conjuntos de caracteres (sem desculpas!) De Joel Spolsky .
fonte
No PHP, a melhor maneira de verificar se uma string contém uma certa substring, é usar uma função auxiliar simples como esta:
Explicação:
strpos
localiza a posição da primeira ocorrência de uma substring que diferencia maiúsculas de minúsculas em uma string.stripos
localiza a posição da primeira ocorrência de uma substring que não diferencia maiúsculas de minúsculas em uma string.myFunction($haystack, $needle) === FALSE ? FALSE : TRUE
garante quemyFunction
sempre retorne um booleano e corrija um comportamento inesperado quando o índice da substring for 0.$caseSensitive ? A : B
selecionastrpos
oustripos
faz o trabalho, dependendo do valor de$caseSensitive
.Resultado:
fonte
A função abaixo também funciona e não depende de nenhuma outra função; ele usa apenas manipulação nativa de strings PHP. Pessoalmente, eu não recomendo isso, mas você pode ver como ele funciona:
Teste:
fonte
Você pode usar a
strstr
função:Sem usar uma função embutida:
fonte
Eu tive alguns problemas com isso e, finalmente, escolhi criar minha própria solução. Sem usar o mecanismo de expressão regular :
Você pode perceber que as soluções anteriores não são uma resposta para a palavra que está sendo usada como prefixo para outra. Para usar seu exemplo:
Com as amostras acima, ambos
$a
e$b
contém$c
, mas você pode querer que sua função diga que apenas$a
contém$c
.fonte
$found = false
no inícioOutra opção para encontrar a ocorrência de uma palavra a partir de uma string usando strstr () e stristr () é a seguinte:
fonte
i
emstristr
significa insensível.Muitas respostas que usam
substr_count
verificações se o resultado é>0
. Mas como aif
instrução considera zero igual a falso , você pode evitar essa verificação e escrever diretamente:Para verificar se não está presente, adicione o
!
operador:fonte
Isso pode ser feito de três maneiras diferentes:
1- stristr ()
2- strpos ()
3- preg_match ()
fonte
A versão abreviada
fonte
Para encontrar uma 'palavra', em vez da ocorrência de uma série de letras que poderiam de fato fazer parte de outra palavra, o seguinte seria uma boa solução.
fonte
$string
forAre are, are?
Você deve usar o formato Insensitive do caso, portanto, se o valor inserido estiver em
small
oucaps
não importar.Aqui stripos encontra agulha no palheiro sem considerar o caso (pequeno / caps).
Amostra PHPCode com saída
fonte
Talvez você possa usar algo como isto:
fonte
Não use
preg_match()
se você deseja apenas verificar se uma sequência está contida em outra. Usestrpos()
ou, emstrstr()
vez disso, pois eles serão mais rápidos. ( http://in2.php.net/preg_match )fonte
Se você deseja verificar se a sequência contém várias palavras específicas, você pode:
Isso é útil para evitar spam ao enviar e-mails, por exemplo.
fonte
A função strpos funciona bem, mas se você deseja
case-insensitive
verificar uma palavra em um parágrafo, pode usar astripos
função dePHP
.Por exemplo,
Encontre a posição da primeira ocorrência de uma substring que não diferencia maiúsculas de minúsculas em uma sequência.
Se a palavra não existir na string, ela retornará false; caso contrário, retornará a posição da palavra.
fonte
Você precisa usar operadores idênticos / não idênticos porque strpos podem retornar 0 como seu valor de índice. Se você gosta de operadores ternários, considere usar o seguinte (parece um pouco ao contrário, admito):
fonte
Isso significa que a string deve ser resolvida em palavras (veja a nota abaixo).
Uma maneira de fazer isso e especificar os separadores é usando
preg_split
( doc ):Uma corrida dá
Nota: Aqui não queremos dizer palavra para cada sequência de símbolos.
Uma definição prática de palavra é, no sentido, o mecanismo de expressão regular do PCRE, onde as palavras são substrings que consistem apenas em caracteres da palavra, sendo separadas por caracteres que não são da palavra.
fonte
Outra solução para uma sequência específica:
Você também pode usar a
strpos()
funçãofonte