Elimina una parte de una cadena, pero solo cuando está al final de la cadena

4 minutos de lectura

avatar de usuario
dylan

Necesito eliminar una subcadena de una cadena, pero solo cuando está al FINAL de la cadena.

por ejemplo, eliminando ‘cadena’ al final de las siguientes cadenas:

"this is a test string" ->  "this is a test "
"this string is a test string" - > "this string is a test "
"this string is a test" -> "this string is a test"

Algunas ideas ? Probablemente algún tipo de preg_replace, pero ¿cómo?

Notarás el uso de la $ carácter, que denota el final de una cadena:

$new_str = preg_replace('/string$/', '', $str);

Si la cadena es una variable proporcionada por el usuario, es una buena idea ejecutarla preg_quote primero:

$remove = $_GET['remove']; // or whatever the case may be
$new_str = preg_replace("https://stackoverflow.com/". preg_quote($remove, "https://stackoverflow.com/") . '$/', '', $str);

  • ¿preg_quote/preg_replace también funcionará con cadenas que no sean ASCII (por ejemplo, UTF-8)? es decir, decir son preg_* familias de funciones conscientes de la codificación? Qué pasa [^[:alnum:]] clase de personaje?

    – Sudhi

    14 de noviembre de 2011 a las 16:40

  • Esto no elimina el espacio antes de “cadena” si existiera. También puede usar una subcadena en los últimos 6 caracteres, compararlos con “cadena” y, si es una coincidencia, subcadenarlos. Sería mucho más rápido que Regex.

    – Cole Tobin

    17 de agosto de 2013 a las 7:30

  • Esta no debería ser la respuesta aceptada. Usar preg_replace para esta tarea es terriblemente feo, erróneo en la lógica y una pérdida total de energía/tiempo/ciclos del servidor (sí, importa, usted paga más por su alojamiento porque 10000000 de las páginas web de otros usuarios usan preg_replace en lugar de substr)

    – FrancescoMM

    16 de septiembre de 2016 a las 9:48

El uso de expresiones regulares puede fallar si la subcadena tiene caracteres especiales.

Lo siguiente funcionará con cualquier cadena:

$substring = 'string';
$str = "this string is a test string";
if (substr($str,-strlen($substring))===$substring) $str = substr($str, 0, strlen($str)-strlen($substring));

  • el último bit puede ser simplemente $str = substr($str, 0, -strlen($substring)); votado como una buena alternativa para expresiones regulares. Se me ocurrió la misma respuesta para mi problema. Yo usaría funciones de cadena puras sobre preg_* familias en cualquier momento si sirve a mi propósito

    – Sudhi

    14 de noviembre de 2011 a las 16:37

  • una solución simple e inteligente para un problema supuestamente simple sin usar expresiones regulares. Gracias

    – aldos

    17 dic 2015 a las 8:30

  • Como dicen algunos, “si su solución requiere expresiones regulares, ahora tiene dos problemas”. Entonces, por el gusto de hacerlo, quería resolver este problema para no expresiones regulares y vine con exactamente esto y el comentario de @Sudhi antes de ver su respuesta. La pequeña pieza de la que no estaba al tanto era que puedes colocar “-” para negar en lugar de multiplicar por -1. Así que gracias.

    – Chronofish

    29/03/2018 a las 15:00


  • Solo una nota: debe usar las funciones mb_* para estar seguro para caracteres especiales (por ejemplo: áéã, etc.)

    – M. César

    4 de marzo de 2019 a las 14:22

avatar de usuario
Bajo

Escribí estas dos funciones para el recorte izquierdo y derecho de una cadena:

/**
 * @param string    $str           Original string
 * @param string    $needle        String to trim from the end of $str
 * @param bool|true $caseSensitive Perform case sensitive matching, defaults to true
 * @return string Trimmed string
 */
function rightTrim($str, $needle, $caseSensitive = true)
{
    $strPosFunction = $caseSensitive ? "strpos" : "stripos";
    if ($strPosFunction($str, $needle, strlen($str) - strlen($needle)) !== false) {
        $str = substr($str, 0, -strlen($needle));
    }
    return $str;
}

/**
 * @param string    $str           Original string
 * @param string    $needle        String to trim from the beginning of $str
 * @param bool|true $caseSensitive Perform case sensitive matching, defaults to true
 * @return string Trimmed string
 */
function leftTrim($str, $needle, $caseSensitive = true)
{
    $strPosFunction = $caseSensitive ? "strpos" : "stripos";
    if ($strPosFunction($str, $needle) === 0) {
        $str = substr($str, strlen($needle));
    }
    return $str;
}

Supongo que te vendría bien un expresión regularque coincidiría string y luego, final de cadenajunto con el preg_replace() función.

Algo como esto debería funcionar bien:

$str = "this is a test string";
$new_str = preg_replace('/string$/', '', $str);

Notas:

  • string partidos… bueno… string
  • y $ significa final de cadena

Para más información, puede leer el Sintaxis de patrones sección del manual de PHP.

preg_replace y este patrón: /string\z/i

\z significa el final de la cadena

http://tr.php.net/preg_replace

avatar de usuario
Marco Panichi

SI no le importa el rendimiento Y la parte de la cadena se puede colocar solo al final de la cadena, ENTONCES puede hacer esto:

$string = "this is a test string";
$part = "string";
$string = implode( $part, array_slice( explode( $part, $string ), 0, -1 ) );
echo $string;
// OUTPUT: "this is a test "

avatar de usuario
kloddant

La respuesta de @ Skrol29 es la mejor, pero aquí está en forma de función y usando el operador ternario:

if (!function_exists('str_ends_with')) {
    function str_ends_with($haystack, $suffix) {
        $length = strlen( $suffix );
        if( !$length ) {
            return true;
        }
        return substr( $haystack, -$length ) === $suffix;
    }
}

if (!function_exists('remove_suffix')) {
    function remove_suffix ($string, $suffix) {
        return str_ends_with($string, $suffix) ? substr($string, 0, strlen($string) - strlen($suffix)) : $string;
    }
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad