Divida la cadena alfanumérica entre los dígitos iniciales y las letras finales

6 minutos de lectura

avatar de usuario
David19801

Tengo una cadena como:

$Order_num = "0982asdlkj";

¿Cómo puedo dividir eso en las 2 variables, con el número como un elemento y luego otra variable con el elemento de letra?

El elemento de número puede tener cualquier longitud de 1 a 4, por ejemplo, y el elemento de letra llena el resto para hacer que cada order_num tenga 10 caracteres en total.

he encontrado el php explode función… pero no sé cómo hacerlo en mi caso porque la cantidad de números está entre 1 y 4 y las letras son aleatorias después de eso, por lo que no hay forma de dividir en una letra en particular.

avatar de usuario
Félix Kling

Puedes usar preg_split usando mirar hacia adelante y mirar hacia atrás:

print_r(preg_split('#(?<=\d)(?=[a-z])#i', "0982asdlkj"));

huellas dactilares

Array
(
    [0] => 0982
    [1] => asdlkj
)

Esto solo funciona si la parte de la letra realmente solo contiene letras y no dígitos.

Actualizar:

Solo para aclarar lo que está pasando aquí:

Las expresiones regulares miran cada posición y si un dígito está antes de esa posición ((?<=\d)) y una letra después ((?=[a-z])), luego coincide y la cadena se divide en esta posición. Todo el asunto es insensible a mayúsculas y minúsculas (i).

  • ¿Cuál es la ventaja de usar split over match?

    – moinudín

    27 de diciembre de 2010 a las 10:32

  • Necesitas escapar de \ en \d.

    – moinudín

    27 de diciembre de 2010 a las 10:33


  • @marcog: Buena pregunta… Solo estaba concentrado en terrible la cadena;) No estoy seguro de si hay alguna ventaja.

    – Félix Kling

    27 de diciembre de 2010 a las 10:34

  • @Columna. Metralla: No siempre hay la única respuesta verdadera a un problema La gente piensa de diferentes maneras. ¡Y conocer diferentes formas de resolver un problema es aún mejor!

    – Félix Kling

    27 de diciembre de 2010 a las 10:42


  • La discusión ha terminado de todos modos. Todo lo que quería es mostrar una manera de hacerlo. No es mi culpa que el OP aceptara la respuesta. Si algunos de ustedes quieren tener la-única-y-verdadera-solución entonces vete y vive en un Nuevo mundo valiente. No olvides que las respuestas no son solo para la persona que pregunta sino también para los que vienen después…

    – Félix Kling

    27 de diciembre de 2010 a las 11:03


avatar de usuario
moinudín

Usar coincidencia_preg() con una expresión regular de (\d+)([a-zA-Z]+). Si desea limitar la cantidad de dígitos de 1 a 4 y las letras de 6 a 9, cámbielo a (\d+{1,4})([a-zA-Z]{6,9}).

preg_match("/(\\d+)([a-zA-Z]+)/", "0982asdlkj", $matches);
print("Integer component: " . $matches[1] . "\n");
print("Letter component: " . $matches[2] . "\n");

Salidas:

Integer component: 0982
Letter component: asdlkj

http://ideone.com/SKtKs

  • $matches = array(); no es realmente necesario. preg_match se asegurará de que la matriz siempre exista, incluso cuando no haya ninguna coincidencia.

    – coadicto

    27 de diciembre de 2010 a las 10:44

  • Además, no necesita escapar \ en \\d+. \d+ es suficiente.

    – coadicto

    27 de diciembre de 2010 a las 10:45


  • @codaddict: Pero es un buen estilo de codificación y más fácil de entender para el programador de PHP menos competente, en mi opinión.

    – Félix Kling

    27 de diciembre de 2010 a las 10:45


  • @codaddict No sabía sobre el array()pero no me gusta no escapar.

    – moinudín

    27 de diciembre de 2010 a las 10:53

  • O use esta expresión aún más simple: /(\d+)(.*)/

    – marcovtwout

    21 de febrero de 2014 a las 11:40

avatar de usuario
coadicto

También puedes hacerlo usando preg_split dividiendo su entrada en el punto que entre los dígitos y las letras:

list($num,$alpha) = preg_split('/(?<=\d)(?=[a-z]+)/i',$Order_num);

Puedes usar una expresión regular para eso.

preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;

Mira esto

<?php
$Order_num = "0982asdlkj";
$split=split("[0-9]",$Order_num);
$alpha=$split[(sizeof($split))-1];
$number=explode($alpha, $Order_num);
echo "Alpha -".$alpha."<br>";
echo "Number-".$number[0];
?>

con saludos

wazzy

  • Actualice su PHP de la versión antigua a algo moderno y vuelva a ejecutarlo

    – Tu sentido común

    27 de diciembre de 2010 a las 11:06

  • @Wazzy: Porque la gente está loca y vota negativamente las respuestas. no me gusta. Para ser justos, su solución no es muy elegante, pero da la solución correcta. No lo votaría a favor, pero tampoco lo rechazaría. +1 de mi para compensar.

    – Félix Kling

    27 de diciembre de 2010 a las 11:07


  • @Columna. Metralla: Funciona bien con PHP 5.3.3

    – Félix Kling

    27 de diciembre de 2010 a las 11:08

  • @Columna. Metralla: Entonces split está en desuso en PHP 5.3 y puede ser reemplazado por preg_split… todavía con split o preg_split funciona. Estoy en contra de votar negativamente sin explicación y Actualice su PHP de la versión antigua a algo moderno y vuelva a ejecutarlo no es una explicación.

    – Félix Kling

    27 de diciembre de 2010 a las 11:25


avatar de usuario
mickmackusa

Mi enfoque preferido sería sscanf() porque es conciso, no necesita expresiones regulares, ofrece la capacidad de convertir el segmento numérico como tipo entero y no genera coincidencias de cadena completa innecesarias como preg_match(). %s sin embargo, se basa en el hecho de que no habrá espacios en blanco en el segmento de letras de la cadena.

Manifestación

$Order_num = "0982asdlkj";
var_export (
    sscanf($Order_num, '%d%s')
);

Esto también se puede configurar para declarar variables individuales.

sscanf($Order_num, '%d%s', $numbers, $letters)

Si desea utilizar un preg_ función, preg_split() es lo más apropiado, pero no usaría soluciones costosas. Haga coincidir los dígitos, luego olvídelos (con \K). Esto dividirá la cadena sin consumir ningún carácter. Manifestación

var_export (
    preg_split('/\d+\K/', $Order_num)
);

Para asignar variables, use “desestructuración de matriz simétrica”.

[$numbers, $letters] = preg_split('/\d+\K/', $Order_num);

Más allá de estos enfoques de una sola función, habrá MUCHOS enfoques de dos funciones como:

$numbers = rtrim($Order_num, 'a..z');
$letters = ltrim($Order_num, '0..9');

Pero no los usaría en un guión profesional porque les falta elegancia.

  • Actualice su PHP de la versión antigua a algo moderno y vuelva a ejecutarlo

    – Tu sentido común

    27 de diciembre de 2010 a las 11:06

  • @Wazzy: Porque la gente está loca y vota negativamente las respuestas. no me gusta. Para ser justos, su solución no es muy elegante, pero da la solución correcta. No lo votaría a favor, pero tampoco lo rechazaría. +1 de mi para compensar.

    – Félix Kling

    27 de diciembre de 2010 a las 11:07


  • @Columna. Metralla: Funciona bien con PHP 5.3.3

    – Félix Kling

    27 de diciembre de 2010 a las 11:08

  • @Columna. Metralla: Entonces split está en desuso en PHP 5.3 y puede ser reemplazado por preg_split… todavía con split o preg_split funciona. Estoy en contra de votar negativamente sin explicación y Actualice su PHP de la versión antigua a algo moderno y vuelva a ejecutarlo no es una explicación.

    – Félix Kling

    27 de diciembre de 2010 a las 11:25


¿Ha sido útil esta solución?