Estoy buscando un método para imprimir el número más largo en una cadena.
Por ejemplo: si tengo la cuerda
212334123434test233
como puedo imprimir
212334123434
?
Nota: Estoy buscando la secuencia continua de números más larga, no el valor numéricamente más alto.
Editar: Gracias por las respuestas, todos. La respuesta a esta pregunta ha sido bastante abrumadora. Marqué la publicación de @ HaukeLaging como la respuesta aceptada porque se adaptaba muy bien a mi caso específico, pero me gustaría señalar que todas las respuestas son igualmente válidas. Siempre es bueno tener varias opciones diferentes para resolver un problema.
text-processing
sed
awk
Glutanimato
fuente
fuente
Respuestas:
fuente
Creo que se puede hacer esto con solo
grep
,sort
ytail
así. Aquí hay algunos ejemplos de cadenas.¿Dónde
<str>
está nuestra cadena en cuestión?Ejemplo
Ahora si ejecuto estos a través de mi
grep ...
comando a su vez.Este enfoque funciona seleccionando todas las subcadenas que son secuencias de dígitos. Luego ordenamos esta salida numéricamente,
sort -n
y luego tomamos el último valor de la lista, usandotail -1
. Esta será la subcadena más larga.Puede ver cómo funciona
tail -1
despegando y volviendo a ejecutar uno de los ejemplos:Cadenas que comienzan con ceros
El enfoque anterior funciona para todas las situaciones que podría concebir, excepto una. @terdon mencionó en el chat este escenario que frustra el enfoque anterior.
Entonces, para lidiar con esto, deberá cambiar ligeramente las tácticas. El núcleo del enfoque anterior todavía se puede aprovechar, sin embargo, también debemos inyectar el número de caracteres en los resultados. Esto le da a la capacidad de ordenar los resultados por número de caracteres en las cadenas y sus valores.
Resultados:
Puede condensar esto un poco haciendo uso de la capacidad de Bash para determinar la longitud de una variable usando
${#var}
.Usando `grep -P
He optado por usarlo
grep -P ...
anteriormente porque, como desarrollador de Perl, me gusta la sintaxis de clase de decir todos los dígitos de esta manera: en\d+
lugar de[[:digit:]]\+
o[0-9]\+
. Pero para este problema en particular no es realmente necesario. Podrías cambiar fácilmente elgrep
que he usado así:Por ejemplo:
fuente
${#i}
para obtener la longitud de la cadena puede ahorrarle llamadaswc
, si desea ir específico de bashgrep -o "[0-9]\+"
lugar degrep -oP "\d+"
Una solución en
perl
:Referencias
fuente
Usando python con la cadena pasada en la línea de comando y suponiendo que desea la primera secuencia de longitud máxima:
fuente
python -c "import re,sys; print max(re.split(r'\D+', sys.argv[1]), key=len)"
Aquí hay otro enfoque de Perl que puede tratar con decimales y enteros:
Tenga en cuenta que ninguna de las respuestas publicadas hasta ahora tratará con decimales y dado que usted especifica que desea el número más largo y no el número numéricamente mayor, supongo que realmente necesita decimales.
Explicación
perl -lne
: Los-n
medios "leen la entrada línea por línea y ejecutan el script dado por-e
ella". El-l
añade una nueva línea para cadaprint
llamada (y otras cosas que no vienen al caso).while(/([\d.]+)/g)
: Iterar a través de todos los números (\d
medios[0-9]
, por lo que[\d.]
coincidirá con dígitos y.
Si también quiere encontrar los números negativos, agregar.-
Los paréntesis capturan la cadena coincidente como.$1
Que se utiliza en el siguiente paso.$max=$1 if length($1) > length($max)
: Si la duración de la coincidencia actual es mayor que la más larga hasta ahora ($max
) guarde la coincidencia como$max
.print $max
: imprime la cadena más larga de números encontrados. Esto se ejecutará después de que finalice el ciclo while, así que después de que se hayan encontrado todos los números.fuente
\D(\d+(?:\.\d+)?)\D
lugar.\D
anclajes ....
como en las direcciones IP.Dado
luego en bash
Una solución bash posiblemente más pura que utiliza una matriz construida reemplazando caracteres que no son dígitos en la cadena con espacios en blanco, en lugar del grep
fuente
Sobre la base de la respuesta de @mikeserv, aquí hay otra alternativa. Extrae los números (según el método de mikeserv), luego los ordena en orden numérico y toma el último. Salvo los ceros iniciales, esto le dará el número más grande (sin tener en cuenta el signo):
fuente
set -- $(echo $str | tr ... ) ; b=${#1} ; for d ; do [ ${#d} -gt $b ] && b=${#d} n=$d ; done ; echo $n
tr
todos modos, no guardaría rencor si incorporaste lo anterior. Probablementesort
sea más rápido, pero, de nuevo, espera a que la transmisión termine igual que el$(subshell)
. No lo sé. En cualquier caso, la suya ya es una excelente respuesta, pero si tiene ganas de agregar el bucle de shell anterior, no dude en decirlo. Y, por cierto, es posible que pueda prescindir porsort
completo con un poco de manejo creativowc -L
ytee
en la transmisión ... Sin embargo, terminé con esta pregunta, estoy avergonzado.tr
salir de la subshell y deshacerse de élprintf
. Solo hazlo'0-9' '\n'
.bash y GNU sort
fuente
Use caracteres no numéricos para dividir la cadena y encuentre la secuencia más larga o el valor numérico más grande (para números de igual longitud) con un operador ternario.
También puede configurar el separador de registros de awk (
RS
) para que sea cualquier cadena de caracteres no numérica:fuente
RS = '[^0-9]+'
y usar el bucle inherente de Awk?echo "212334123434test233" | awk -v RS='[^0-9]+' 'length(longest) < length($0) {longest = $0};END{print longest}' 212334123434
RS
variable, debo admitir que es la primera vez que la veo. Tienes más consejos que ofrecerawk
que yo jajaja!