¿Cómo puedo escribir dos funciones que tomarían una cadena y regresarían si comienza con el carácter / cadena especificado o termina con él?
Por ejemplo:
$str = '|apples}';
echo startsWith($str, '|'); //Returns true
echo endsWith($str, '}'); //Returns true
s($str)->startsWith('|')
ys($str)->endsWith('}')
útil, como se encuentra en esta biblioteca independiente .Respuestas:
Use esto si no quiere usar una expresión regular.
fuente
$length
no es necesario en la última línea de laendsWith()
.return substr($haystack, -strlen($needle))===$needle;
if
completo haciendo pasar$length
como tercer parámetro asubstr
:return (substr($haystack, -$length, $length);
. Esto maneja el caso$length == 0
devolviendo una cadena vacía y no la totalidad$haystack
.Puede usar la
substr_compare
función para verificar el inicio y el final con:Esta debería ser una de las soluciones más rápidas en PHP 7 ( script de referencia ). Probado contra pajar de 8KB, agujas de diferentes longitudes y casos completos, parciales y sin coincidencia.
strncmp
es un toque más rápido para comenzar, pero no puede verificar termina con.fuente
strrpos
cuál (debería) fallar inmediatamente si la aguja no coincide con el comienzo del pajar.-strlength($haystack)
) y buscando hacia atrás desde allí. ¿Eso no significa que no estás buscando nada? Tampoco entiendo las!== false
partes de esto. Supongo que esto se basa en una peculiaridad de PHP donde algunos valores son "verdaderos" y otros "falsos", pero ¿cómo funciona eso en este caso?xxxyyy
needle =yyy
y el uso destrrpos
la búsqueda comienza desde el primerox
. Ahora no tenemos una coincidencia exitosa aquí (se encuentra x en lugar de y) y no podemos retroceder más (estamos al comienzo de la cadena) la búsqueda falla inmediatamente . Acerca del uso!== false
:strrpos
en el ejemplo anterior devolverá 0 o falso y no otro valor. Del mismo modo,strpos
en el ejemplo anterior puede devolver$temp
(la posición esperada) o falso. Fui con!== false
coherencia, pero podría usar=== 0
y=== $temp
en las funciones respectivamente.Actualizado 23-ago-2016
Las funciones
Pruebas
Resultados (PHP 7.0.9)
(Ordenado más rápido a más lento)
Resultados (PHP 5.3.29)
(Ordenado más rápido a más lento)
comienza con_benchmark.php
fuente
function startswith5b($haystack, $needle) {return ($haystack{0}==$needle{0})?strncmp($haystack, $needle, strlen($needle)) === 0:FALSE;}
agregué una respuesta a continuación.Todas las respuestas parecen tan lejos para hacer un montón de trabajo innecesario,
strlen calculations
,string allocations (substr)
, etc.'strpos'
y'stripos'
funciones devuelven el índice de la primera aparición de$needle
en$haystack
:fuente
endsWith()
La función tiene un error. Su primera línea debería ser (sin el -1):$expectedPosition = strlen($haystack) - strlen($needle);
strpos($haystack, "$needle", 0)
si hubiera alguna posibilidad de que no sea una cuerda (por ejemplo, si provienejson_decode()
). De lo contrario, el comportamiento predeterminado [impar] destrpos()
puede causar resultados inesperados: " Si la aguja no es una cadena, se convierte en un entero y se aplica como el valor ordinal de un carácter " .Crédito a :
Compruebe si una cadena termina con otra cadena
Compruebe si una cadena comienza con otra cadena
fuente
El regex funciona arriba, pero con los otros ajustes también sugeridos arriba:
fuente
Esta pregunta ya tiene muchas respuestas, pero en algunos casos puede conformarse con algo más simple que todas. Si la cadena que está buscando es conocida (codificada), puede usar expresiones regulares sin comillas, etc.
Compruebe si una cadena comienza con 'ABC':
termina con 'ABC':
En mi caso simple, quería verificar si una cadena termina con una barra inclinada:
La ventaja: dado que es muy corto y simple, no tiene que definir una función (como
endsWith()
) como se muestra arriba.Pero, una vez más, esta no es una solución para cada caso, solo esta muy específica.
fuente
@
, para que la barra (/
) no tenga que escaparse. Vea el Ejemplo # 3 aquí: php.net/manual/en/function.preg-match.php .Si la velocidad es importante para usted, intente esto (creo que es el método más rápido)
Funciona solo para cadenas y si $ haystack es solo 1 carácter
fuente
endsWithChar('','x')
pero el resultado es correctoAquí hay dos funciones que no introducen una cadena temporal, que podrían ser útiles cuando las agujas son sustancialmente grandes:
fuente
endsWidth
debería hacerloreturn $needle==='' || substr_compare(
... así que funciona como se esperaba para lo-strlen($needle)===0
cual, sin la solución,endsWith('a','')
regresafalse
substr_compare()
realidad, así que agregué un RP para arreglar eso :)endsWith('', 'foo')
activa una Advertencia: "substr_compare (): La posición de inicio no puede exceder la longitud inicial de la cadena". Tal vez sea otro errorsubstr_compare()
, pero para evitarlo, necesita una verificación previa como ...|| (strlen($needle) <= strlen($haystack) && substr_compare(
...) === 0);
return $needle === '' || @substr_compare(
... para suprimir esta advertencia.Fin más rápido con la solución ():
Punto de referencia:
Resultados de referencia:
fuente
Me doy cuenta de que esto se ha terminado, pero es posible que desee ver strncmp ya que le permite poner la longitud de la cadena para comparar, por lo que:
fuente
Puedes usar
strpos
ystrrpos
fuente
strpos($sHaystack, $sNeedle) == 0
como estestrpos($sHaystack, $sNeedle) === 0
? Veo un error, cuando sefalse == 0
evalúatrue
.Aquí hay una versión segura de varios bytes de la respuesta aceptada, funciona bien para cadenas UTF-8:
fuente
startsWith
debe ser$length = mb_strlen($needle, 'UTF-8');
Líneas cortas y fáciles de entender sin expresiones regulares.
comienza con () es sencillo.
endsWith () usa el strrev () ligeramente elegante y lento:
fuente
Centrándose en el inicio, si está seguro de que las cadenas no están vacías, agregar una prueba en el primer carácter, antes de la comparación, el strlen, etc., acelera un poco las cosas:
Es de alguna manera (20% -30%) más rápido. Agregar otra prueba de caracteres, como $ haystack {1} === $ needle {1} no parece acelerar mucho las cosas, incluso puede disminuir la velocidad.
===
parece más rápido que el==
operador condicional(a)?b:c
parece más rápido queif(a) b; else c;
Para aquellos que preguntan "¿por qué no usar strpos?" llamando a otras soluciones "trabajo innecesario"
strpos es rápido, pero no es la herramienta adecuada para este trabajo.
Para entender, aquí hay una pequeña simulación como ejemplo:
¿Qué hace la computadora "adentro"?
Asumir que strlen no itera la cadena completa (pero incluso en ese caso) esto no es conveniente en absoluto.
fuente
Espero que la respuesta a continuación sea eficiente y simple:
fuente
Por lo general, termino yendo con una biblioteca como underscore-php en estos días.
La biblioteca está llena de otras funciones útiles.
fuente
La respuesta de mpen es increíblemente exhaustiva, pero, desafortunadamente, el punto de referencia proporcionado tiene una supervisión muy importante y perjudicial.
Debido a que cada byte en agujas y pajares es completamente aleatorio, la probabilidad de que un par aguja-pajar difiera en el primer byte es 99.609375%, lo que significa que, en promedio, aproximadamente 99609 de los 100000 pares diferirán en el primer byte . En otras palabras, el punto de referencia está fuertemente sesgado hacia
startswith
implementaciones que verifican el primer byte explícitamente, comostrncmp_startswith2
hace.Si el bucle generador de prueba se implementa de la siguiente manera:
Los resultados de referencia cuentan una historia ligeramente diferente:
Por supuesto, este punto de referencia todavía puede no ser perfectamente imparcial, pero también prueba la eficiencia de los algoritmos cuando se les dan agujas que coinciden parcialmente.
fuente
en breve:
fuente
Solo una recomendación:
Esa línea adicional, que compara el primer carácter de las cadenas, puede hacer que el caso falso regrese de inmediato , por lo que muchas de sus comparaciones son mucho más rápidas (7 veces más rápido cuando medí). En el caso real, prácticamente no paga precio por el rendimiento de esa línea, así que creo que vale la pena incluirlo. (Además, en la práctica, cuando prueba muchas cadenas para un fragmento inicial específico, la mayoría de las comparaciones fallarán, ya que en un caso típico está buscando algo).
fuente
startsWith("123", "0")
datrue
La
substr
función puede volverfalse
en muchos casos especiales, así que aquí está mi versión, que trata estos problemas:Pruebas (
true
significa bueno):Además, la
substr_compare
función también vale la pena mirar. http://www.php.net/manual/en/function.substr-compare.phpfuente
Esto puede funcionar
Fuente: https://stackoverflow.com/a/4419658
fuente
Lo haría asi
fuente
Basado en la respuesta de James Black, aquí está su final con la versión:
Nota: He cambiado la parte if-else por la función startWith de James Black, porque strncasecmp es en realidad la versión de strncmp que no distingue entre mayúsculas y minúsculas.
fuente
strrev()
es creativo pero muy costoso, especialmente si tiene cadenas de decir ... 100Kb.===
lugar de==
estar seguro.0
es igual a muchas cosas en PHP.¿Por qué no lo siguiente?
Salida:
Tenga en cuenta
strpos
que devolverá falso si no se encontró la aguja en el pajar y devolverá 0 si, y solo si, se encontró la aguja en el índice 0 (también conocido como el comienzo).Y aquí termina: con:
En este escenario no hay necesidad de que una función empiece con () como
devolverá verdadero o falso con precisión.
Parece extraño que sea así de simple con todas las funciones salvajes que se ejecutan desenfrenadamente aquí.
fuente
strpos()
será lento, excepto cuando coincida.strncmp()
Sería mucho mejor en este caso.Muchas de las respuestas anteriores funcionarán igual de bien. Sin embargo, esto es posiblemente lo más corto posible y lograr que haga lo que desee. Simplemente declaras que te gustaría que 'vuelva verdadero'. Así que he incluido soluciones que devuelven boolean verdadero / falso y el texto verdadero / falso.
fuente
'true'
y'false'
como cadenas, que son ambastrue
en un sentido booleano. Sin embargo, es un buen patrón para algo como underhanded.xcott.com ;)También puedes usar expresiones regulares:
fuente
preg_quote($needle, '/')
.Sin copia y sin bucle interno:
fuente
Aquí hay una solución eficiente para PHP 4. Puede obtener resultados más rápidos si usa PHP 5 utilizando en
substr_compare
lugar destrcasecmp(substr(...))
.fuente
Puede usar la función fnmatch para esto.
fuente