2016-05-03 10 views
0

Ich versuche, die erste Instanz des Wertes des Zeitstempels in einem Ausdruck und die letzten Instanz des Wertes der Zeitmarke in einem anderen Ausdruck entsprechen:Erhalten erste Instanz und Erhalten letzte Instanz String

{ ‚Latitude‘: 50.00001, 'Länge': 2.00002, 'Zeitstempel': '00: 10: 00 '}, {' Breite ': 50.0,' Länge ': 2.0,' Zeitstempel ': '00: 20: 00'}, {'Breite ': 50.0,' Länge ': 2.0,' Zeitstempel ': '00: 25: 00'}, {'Breite': 50.0, 'Länge': 2.0, 'Zeitstempel': '00: 37: 00 '}

Wer weiß, wie man das macht.

+0

Von Ihrem Beispiel, können Sie darauf hinweisen, was Sie übereinstimmen möchten? – sehrob

+0

Bitte überprüfen Sie dies: https://regex101.com/r/zL2uZ4/1 – AKS

Antwort

2

Nutzen Sie die Gierigkeit von regexp: Der Operator * nimmt so viele Treffer wie möglich. Der Ansatz besteht also darin, das explizite Muster am Anfang und Ende der Regexp mit einem .* in der Mitte zu vergleichen. Die .* wird so viele Zeichen schlürfen, wie es dem Rest der Regexp entsprechen kann.

/(${pattern}).*(${pattern})/ 

Hier steht $ {} für Extrapolation. Dies hängt von Ihrer Sprache ab. In Ruby wäre es # {}. Ich habe mich entschieden, das gesamte Muster zu erfassen. Sie können stattdessen das Capture() um den Timestamp-Wert legen, aber ich finde es einfacher zu lesen und zu warten. Diese Regexp passt zwei Instanzen von $ pattern mit so viel dazwischen wie es passt, was garantiert, dass Sie die erste und letzte haben.

Wenn Sie mehr streng sein wollen, können Sie das Muster in der Mitte durchzusetzen als auch, * ‚ing das volle Muster anstatt nur .:

/${pattern},\s*(?:${pattern},\s*)*${pattern}/ 

in den Kommentaren fragen, wenn Sie nicht tun verstehe jedes Stück dieser Regexp.

Ein Muster, das wir verwenden können, ist /\{[^}]+\'Timestamp\'[^}]+\}/. Beachten Sie, dass dieses Muster annimmt, dass Timestamp der LETZTE Schlüssel ist; Wenn das nicht immer der Fall ist, müssen Sie diesem Muster etwas mehr hinzufügen.

So das Gesamtmuster für das erste Beispiel wird sein:

str =~ /(${pattern}.*(${pattern})/ 

Oder ohne Extrapolation:

str =~ /({[^}]+'Timestamp'[^}]+}).*({[^}]+'Timestamp'[^}]+})/ 

Dann $1 und $2 die ersten und letzten Hashes sind, die die Timestamp Schlüssel entsprechen . Dies entspricht wiederum dem gesamten Muster und nicht nur dem Timestamp-Wert selbst, aber von dort sollte es einfach sein, den tatsächlichen Timestamp-Wert zu extrahieren.

Für das zweite, strengere Beispiel, und der Grund warum ich nicht den Zeitstempel-Wert innerhalb des Musters selbst erfassen wollte, haben wir:

str =~ /(${pattern}),\s*(?:${pattern},\s*)*(${pattern})/ 

Oder ohne Extrapolation:

str =~ /({[^}]+'Timestamp'[^}]+}), *(?:{[^}]+'Timestamp'[^}]+}, *)*({[^}]+'Timestamp'[^}]+})/ 

Wir haben immer noch die korrekten Ergebnisse in $1 und $2, weil wir explizit entschieden, KEINE einzufangende Gruppe innerhalb des Musters zu setzen.

+0

Das ist großartig.Werde das jetzt testen – wingyip

+0

Funktioniert ein Genuss! Vielen Dank. – wingyip

Verwandte Themen