php - texto - strpos() con agujas multiples?
string strip_tags (5)
Aquí hay un código de ejemplo para mi estrategia:
function strpos_array($haystack, $needles, $offset=0) {
$matches = array();
//Avoid the obvious: when haystack or needles are empty, return no matches
if(empty($needles) || empty($haystack)) {
return $matches;
}
$haystack = (string)$haystack; //Pre-cast non-string haystacks
$haylen = strlen($haystack);
//Allow negative (from end of haystack) offsets
if($offset < 0) {
$offset += $heylen;
}
//Use strpos if there is no array or only one needle
if(!is_array($needles)) {
$needles = array($needles);
}
$needles = array_unique($needles); //Not necessary if you are sure all needles are unique
//Precalculate needle lengths to save time
foreach($needles as &$origNeedle) {
$origNeedle = array((string)$origNeedle, strlen($origNeedle));
}
//Find matches
for(; $offset < $haylen; $offset++) {
foreach($needles as $needle) {
list($needle, $length) = $needle;
if($needle == substr($haystack, $offset, $length)) {
$matches[] = $offset;
break;
}
}
}
return($matches);
}
He implementado un método simple de fuerza bruta que funciona con cualquier combinación de agujas y pajares (no solo palabras). Para los algoritmos posiblemente más rápidos revisa:
Otra solucion
function strpos_array($haystack, $needles, $theOffset=0) {
$matches = array();
if(empty($haystack) || empty($needles)) {
return $matches;
}
$haylen = strlen($haystack);
if($theOffset < 0) { // Support negative offsets
$theOffest += $haylen;
}
foreach($needles as $needle) {
$needlelen = strlen($needle);
$offset = $theOffset;
while(($match = strpos($haystack, $needle, $offset)) !== false) {
$matches[] = $match;
$offset = $match + $needlelen;
if($offset >= $haylen) {
break;
}
}
}
return $matches;
}
Estoy buscando una función como strpos () con dos diferencias significativas:
- Para poder aceptar agujas múltiples. Me refiero a miles de agujas a las unas.
- Para buscar todas las apariciones de las agujas en el pajar y devolver una serie de posiciones iniciales.
Por supuesto, tiene que ser una solución eficiente, no solo un bucle a través de cada aguja. He buscado en este foro y hubo preguntas similares a esta, como:
- Usando una matriz como agujas en strpos
- Definir múltiples agujas utilizando stripos.
- No se puede buscar en una matriz en PHP in_array la presencia de múltiples agujas
pero ninguno de ellos era lo que buscaba. Estoy usando strpos solo para ilustrar mejor mi pregunta, probablemente para este propósito se deba usar algo completamente diferente.
Soy consciente de Zend_Search_Lucene y me interesa si se puede usar para lograr esto y cómo (solo la idea general).
Muchas gracias por tu ayuda y tiempo!
Intenta igualar para múltiples
if (preg_match(''/word|word2/i'', $str))
Parece que estás buscando palabras completas . En este caso, algo como esto podría ayudar. Como utiliza funciones integradas, debe ser más rápido que el código personalizado, pero debe perfilarlo:
$words = str_word_count($str, 2);
$word_position_map = array();
foreach($words as $position => $word) {
if(!isset($word_position_map[$word])) {
$word_position_map[$word] = array();
}
$word_position_map[$word][] = $position;
}
// assuming $needles is an array of words
$result = array_intersect_key($word_position_map, array_flip($needles));
Almacenar la información (como las agujas) en el formato correcto mejorará el tiempo de ejecución (por ejemplo, ya que no tiene que llamar a array_flip
).
Nota de la documentación de str_word_count
:
Para el propósito de esta función, ''palabra'' se define como una cadena dependiente de la configuración regional que contiene caracteres alfabéticos, que también pueden contener, pero no comenzar con los caracteres "''" y "-".
Así que asegúrate de establecer la ubicación correcta.
Podrías usar una expresión regular, soportan operaciones O. Sin embargo, esto lo haría bastante lento, en comparación con los strpos.
Sé que esto no responde a la pregunta del OP, pero quería hacer un comentario ya que esta página está en la parte superior de Google para strpos con múltiples agujas. Aquí hay una solución simple para hacerlo (nuevamente, esto no es específico de la pregunta del OP, lo siento):
$img_formats = array(''.jpg'',''.png'');
$missing = array();
foreach ( $img_formats as $format )
if ( stripos($post[''timer_background_image''], $format) === false ) $missing[] = $format;
if (count($missing) == 2)
return array("save_data"=>$post,"error"=>array("message"=>"The background image must be in a .jpg or .png format.","field"=>"timer_background_image"));
Si se agregan 2 elementos a la matriz $ faltante, eso significa que la entrada no satisface ninguno de los formatos de imagen de la matriz $ img_formats. En ese momento, sabe que puede devolver un error, etc. Esto podría convertirse fácilmente en una pequeña función:
function m_stripos( $haystack = null, $needles = array() ){
//return early if missing arguments
if ( !$needles || !$haystack ) return false;
// create an array to evaluate at the end
$missing = array();
//Loop through needles array, and add to $missing array if not satisfied
foreach ( $needles as $needle )
if ( stripos($haystack, $needle) === false ) $missing[] = $needle;
//If the count of $missing and $needles is equal, we know there were no matches, return false..
if (count($missing) == count($needles)) return false;
//If we''re here, be happy, return true...
return true;
}
De vuelta a nuestro primer ejemplo usando la función en su lugar:
$needles = array(''.jpg'',''.png'');
if ( !m_strpos( $post[''timer_background_image''], $needles ) )
return array("save_data"=>$post,"error"=>array("message"=>"The background image must be in a .jpg or .png format.","field"=>"timer_background_image"));
Por supuesto, lo que haga después de que la función devuelva verdadero o falso depende de usted.