Ich suche nach einer Methode, um die längste Zahl in einer Zeichenfolge zu drucken.
ZB: Wenn ich die Schnur habe
212334123434test233
Wie kann ich drucken?
212334123434
?
Hinweis: Ich suche nach der längsten fortlaufenden Folge von Zahlen, nicht nach dem numerisch höheren Wert.
Edit: Danke für die Antworten, alle zusammen. Die Antwort auf diese Frage war ziemlich überwältigend. Ich habe den Beitrag von @ HaukeLaging als akzeptierte Antwort markiert, da er sehr gut zu meinem speziellen Fall passt, aber ich möchte darauf hinweisen, dass alle Antworten gleichermaßen gültig sind. Es ist immer toll, verschiedene Optionen zu haben, um ein Problem zu lösen.
text-processing
sed
awk
Glutanimat
quelle
quelle
Antworten:
quelle
Ich glaube , Sie können dies tun , mit nur
grep
,sort
undtail
außerdem. Hier sind einige Beispielzeichenfolgen.Wo
<str>
ist unsere Schnur in Frage.Beispiel
Nun, wenn ich diese
grep ...
nacheinander durch meinen Befehl laufen lasse.Bei diesem Ansatz werden alle Teilzeichenfolgen ausgewählt, bei denen es sich um Ziffernfolgen handelt. Wir sortieren diese Ausgabe dann numerisch
sort -n
und greifen dann mit auf den letzten Wert in der Liste zutail -1
. Dies ist der längste Teilstring.Sie können sehen, wie es funktioniert, indem
tail -1
Sie eines der Beispiele abnehmen und erneut ausführen:Zeichenfolgen, die mit Nullen beginnen
Der obige Ansatz funktioniert für jede Situation, die ich mir vorstellen kann, außer für eine. @terdon erwähnte im Chat dieses Szenario, das den obigen Ansatz vereitelt.
Um damit fertig zu werden, müssen Sie die Taktik leicht ändern. Der Kernel des obigen Ansatzes kann weiterhin genutzt werden, wir müssen jedoch auch die Anzahl der Zeichen in die Ergebnisse einfügen. Dies gibt sort die Möglichkeit, die Ergebnisse nach Anzahl der Zeichen in den Zeichenfolgen und deren Werten zu sortieren.
Ergebnisse:
Sie können dies ein wenig komprimieren, indem Sie die Fähigkeit von Bash nutzen, die Länge einer Variablen mithilfe von zu bestimmen
${#var}
.Mit `grep -P
Ich habe mich für die
grep -P ...
obige Verwendung entschieden, weil ich als Perl-Entwickler die Klassensyntax mag, alle Ziffern so zu sagen :\d+
, anstelle von[[:digit:]]\+
oder[0-9]\+
. Aber für dieses spezielle Problem wird es nicht wirklich benötigt. Sie können das, wasgrep
ich verwendet habe, genauso gut austauschen :Beispielsweise:
quelle
${#i}
zum Abrufen der Zeichenfolgenlänge kann Ihnen das Anrufen ersparenwc
, wenn Sie bash-spezifisch werden möchtengrep -o "[0-9]\+"
anstelle vongrep -oP "\d+"
Eine Lösung in
perl
:Verweise
quelle
Verwenden von Python mit der in der Befehlszeile übergebenen Zeichenfolge und vorausgesetzt, Sie möchten die erste Sequenz mit maximaler Länge:
quelle
python -c "import re,sys; print max(re.split(r'\D+', sys.argv[1]), key=len)"
Hier ist ein weiterer Perl-Ansatz, der sowohl mit Dezimalstellen als auch mit ganzen Zahlen umgehen kann:
Beachten Sie, dass sich keine der bisher veröffentlichten Antworten mit Dezimalstellen befasst. Da Sie angeben, dass Sie die längste und nicht die numerisch größte Zahl möchten, gehe ich davon aus, dass Sie diese tatsächlich benötigen gehe Dezimalstellen .
Erläuterung
perl -lne
: Das-n
bedeutet "Lesen Sie die Eingabe Zeile für Zeile und führen Sie das darauf angegebene Skript-e
aus". Das-l
fügt jedemprint
Anruf eine neue Zeile hinzu (und andere Dinge, die hier nicht relevant sind).while(/([\d.]+)/g)
: Durchlaufen Sie alle Zahlen (\d
bedeutet[0-9]
, dass[\d.]
die Ziffern übereinstimmen und.
. Wenn Sie auch negative Zahlen suchen möchten, fügen Sie hinzu-
. Die Klammern erfassen die übereinstimmende Zeichenfolge, wie$1
sie im nächsten Schritt verwendet wird.$max=$1 if length($1) > length($max)
: Wenn die Länge der aktuellen Übereinstimmung größer als die bisher längste ist ($max
), speichern Sie die Übereinstimmung als$max
.print $max
: Gibt die längste gefundene Zahlenfolge aus. Dies wird ausgeführt, nachdem die while-Schleife beendet ist, also nachdem alle Zahlen gefunden wurden.quelle
\D(\d+(?:\.\d+)?)\D
stattdessen so etwas vor.\D
Anker funktionieren ....
wie in IP-Adressen als konsekutiv angesehen .Gegeben
dann in bash
Eine möglicherweise reinere Bash-Lösung, bei der ein Array verwendet wird, bei dem nicht-stellige Zeichen in der Zeichenfolge anstelle von grep durch Leerzeichen ersetzt werden
quelle
Aufbauend auf der Antwort von @mikeserv gibt es hier noch eine weitere Alternative. Es extrahiert die Zahlen (nach der Methode von mikeserv), sortiert sie dann in numerischer Reihenfolge und nimmt die letzte. Abgesehen von führenden Nullen erhalten Sie die größte Zahl (ohne Berücksichtigung des Vorzeichens):
quelle
set -- $(echo $str | tr ... ) ; b=${#1} ; for d ; do [ ${#d} -gt $b ] && b=${#d} n=$d ; done ; echo $n
tr
sowieso schon verwenden, würde ich keinen Groll ertragen, wenn Sie das oben genannte einbeziehen. Wahrscheinlichsort
ist es schneller, aber andererseits wartet es auf das Ende des Streams genauso wie das$(subshell)
. Ich weiß es nicht. In jedem Fall ist Ihre Antwort bereits eine ausgezeichnete, aber wenn Sie Lust haben, die obige Shell-Schleife hinzuzufügen, fühlen Sie sich frei, das ist alles, was ich sage. Übrigens - es ist möglich, dass Siesort
mit ein wenig kreativem Umgang mitwc -L
undtee
im Stream ganz darauf verzichten können ... Ich bin jedoch mit dieser Frage fertig - es ist mir peinlich.tr
aus der Unterschale ziehen und loswerdenprintf
. Tu es einfach'0-9' '\n'
.Bash und GNU sortieren
quelle
Verwenden Sie nicht numerische Zeichen, um die Zeichenfolge zu teilen und die längste Sequenz oder den größten numerischen Wert (für Zahlen gleicher Länge) mit einem ternären Operator zu ermitteln.
Sie können das Datensatztrennzeichen (
RS
) von awk auch auf eine beliebige nicht numerische Zeichenfolge setzen:quelle
RS = '[^0-9]+'
Awks inhärente Schleife setzen und verwenden?echo "212334123434test233" | awk -v RS='[^0-9]+' 'length(longest) < length($0) {longest = $0};END{print longest}' 212334123434
RS
Variable gezeigt hast . Ich muss zugeben, dass ich sie zum ersten Mal sehe. Sie haben mehr Tipps zu bietenawk
als ich, hahaha!