Verwenden von Regex, um eckige Klammern zu findenIch habe einen Kunden, der die Zahlen für Spezifikationsgrenzen extrahieren möchte. Er kann dies tun, wenn der Text Klammern verwendet, nicht jedoch bei eckigen Klammern.Da eckige Klammern „[“ und „]“ spezielle Regex-Zeichen sind, dachte ich, dass die Verwendung des Escape-Zeichens „\“ oder „\\“ helfen würde, aber ich konnte es nicht zum Laufen bringen.
Der Text, den er durchsucht, könnte wie folgt aussehen: [0,080, 1,20] und er möchte Regex verwenden, um 0,080 und 1,2 zu erhalten.
Seine aktuelle Formel zum Finden der linken Klammern „(“ im Text sieht folgendermaßen aus:
Regex( :Text, "((?<=\().+(?=\,))" )
Für rechte Klammern verwendet er „)“.
Regex( :Text, "((?<=\,).+(?=\)))" )
Wie können diese Formeln geändert werden, um „[“ oder „]“ zu finden?
Nachdem er das verstanden hat, möchte er auch „<“, „>“, „+“, „-“ und „+/-“ finden können.
Jede Hilfe wäre dankbar.
Danke!
Betreff: Regex verwenden, um eckige Klammern zu findenDas bringt mich immer zum Stolpern, weil \[ die Escape-Sequenz zum Abgrenzen einer Zeichenfolge ist. Wenn Sie es zuerst maskieren, können Sie es verwenden, um ein Regex-Metazeichen zu kennzeichnen
Num( Regex( :String, "\!\[([0-9\.eE\+\-]+)", "\1" ) )
für die erste Nummer
Num( Regex( :String, "\!\[([0-9\.eE\+\-]+)\s*,([0-9\.eE\+\-]+)", "\2" ) )
zum zweiten.
Betreff: Regex verwenden, um eckige Klammern zu findenHallo Charlie,
Haben Sie eine Vorstellung davon, wie der Text aussehen soll? Der Kunde benötigt möglicherweise nicht einmal Regex. In Umgebungen, in denen dies der Fall ist, ist die resultierende JSL oft viel einfacher zu implementieren und zu warten.
Zum Beispiel:
Names Default To Here(1);
text = "this is a bunch of text with some data in it between brackets [2.3, 4.5] like so.";
specTxt = word(2, text, "[]");
specLo = num(word(1, specTxt, ","));
specHi = num(word(2, specTxt, ","));
show(specLo, specHi);
Betreff: Regex verwenden, um eckige Klammern zu findenAber warum einen Hefthammer verwenden, wenn ein 16-Pfund-Vorschlaghammer einen größeren Knall erzeugt?
Betreff: Mit Regex eckige Klammern findenHat! So wahr.
Betreff: Regex verwenden, um eckige Klammern zu findenDies ist eine großartige Frage, die der Benutzer im posten kann Diskussionen Forum, um die Geschwindigkeit und Qualität der Antworten zu sehen, die sie von der größeren JMP-Benutzergemeinschaft erhalten.
Ich persönlich habe Regex nie gelernt, also verlasse ich mich auf das Zeichenfunktionen für die meisten String-Manipulationen. Insbesondere die Word()-Funktion wirkt bei mir wahre Wunder.
Wenn Sie nur eine Funktion des Formeleditors erlernen, ist Word() die richtige
Betreff: Regex verwenden, um eckige Klammern zu findenDas ist eine tolle Idee. Ich wäre auch gespannt, wie oft die Leute das tun, was ich getan habe, die Frage direkt beantworten, anstatt darüber nachzudenken, was der Benutzer zu tun versucht, um eine einfache und elegantere Lösung zu finden. Es ist immer besser zu verstehen, was der Benutzer braucht und nicht unbedingt, was er will.
Betreff: Regex verwenden, um eckige Klammern zu findenHier ist ein weiteres Beispiel dafür, wie ein regulärer Ausdruck verwendet werden könnte.
Names Default to Here( 1 );
// source
string = "My spec limits are [0.080,1.20] for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),(\d*\.?\d*)", "\2" ) );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Betreff: Regex verwenden, um eckige Klammern zu findenDanke Brady!Ich habe deine Lösung ausprobiert und sie funktioniert.Ich mag die Einfachheit.Gibt es eine Möglichkeit, eine Wortsuche nach „[“ oder „(“ durchzuführen?Ich denke, das entspricht eher dem, was der Kunde sucht.
Danke noch einmal!
Charlie
Betreff: Regex verwenden, um eckige Klammern zu findenDanke Don!Ihre Lösung funktioniert für eckige Klammern.Gibt es eine Möglichkeit, entweder nach „(“ oder „[“ suchen zu lassen, sodass es in beiden Fällen funktioniert?
Danke!
Charlie
Betreff: Regex verwenden, um eckige Klammern zu findenMarkieren-
Ich hatte ein wenig Schwierigkeiten, Ihre Lösung zum Laufen zu bringen.Ich habe eine Beispieldatentabelle beigefügt.Könnten Sie einen Blick darauf werfen und mir mitteilen, was ich falsch mache?
Danke,
Charlie
Betreff: Regex verwenden, um eckige Klammern zu findenDanke Jeff.Ich kenne mich mit Regex überhaupt nicht aus und versuche auch, die Zeichenfunktionen zu verwenden.Allerdings wollte ich die Frage des Kunden mit einer Technik beantworten, die seiner Vorgehensweise sehr ähnlich ist, damit er sie einfach anwenden kann.
Ich habe ihn ermutigt, es in der Community zu veröffentlichen.Mal sehen was passiert.
Danke!
Charlie
Betreff: Regex verwenden, um eckige Klammern zu findenHallo Charlie,
Die Funktion word() verfügt über drei Argumente, von denen das letzte, das festgelegte Trennzeichen, optional ist. Dies ist eine Zeichenfolge in Anführungszeichen, die alle Trennzeichen enthält, die Sie berücksichtigen möchten. Der Benutzer würde also Klammern und Klammern in diese Zeichenfolge einfügen.
Um zu sehen, wie word( ) eine Funktion aufteilt, kann es hilfreich sein, zu untersuchen, was von der Funktion Words() zurückgegeben wird. Words() gibt nach der Begrenzung eine Liste aller Textfragmente zurück.
Zum Beispiel:
Wort (2, „Hit the road jack“) gibt „the“ zurück.
word(2, „Hit the road jack“, „“) gibt „i“ zurück, da die leere Zeichenfolge verwendet wird, wenn Sie den Text in einzelne Zeichen aufteilen möchten.
word(1, "abc/def[ghi]klm", "[]()") gibt "abc/def" zurück... wenn Sie sich Wörter( "abc/def[ghi]klm", "[]()" ) ansehen, erhalten Sie
{ "abc/def", "ghi", "klm" } als Ergebnis.
Hoffe das hilft.
Beifall,
Brady
Betreff: Regex verwenden, um eckige Klammern zu findenWenn Sie wirklich Regex verwenden möchten, kann die folgende Zeichenfolge für Upper oder Lower verwendet werden
"[\!\[|\(]([0-9\.eE\+\-]+)\s*,\s*([0-9\.eE\+\-]+)"
Der einzige Unterschied besteht im zweiten Argument, „\1“ für das untere und „\2“ für das obere. Um zu verstehen, worum es geht, stellen Sie sich den Ausdruck als vierteilig vor
[\!\[|\(]
[a|b] entspricht entweder a oder b. Sowohl die eckigen Klammern als auch die Klammern sind Sonderzeichen und müssen daher durch den Backslash maskiert werden. Da die Sequenz \[ auch in JSL etwas Besonderes ist, benötigt sie das ! um anzuzeigen, dass es sich nicht um eine spezielle Sequenz handelt.
([0-9\.eE\+\-]+)
Die Klammern erfassen den darin enthaltenen Ausdruck. Darauf bezieht sich \1. Auch hier werden die eckigen Klammern zur Bezeichnung eines Zeichensatzes verwendet. In diesem Fall handelt es sich um eine oder mehrere (aufgrund des + am Ende) einer Zahl, eines Punkts (Sonderzeichen mit Escapezeichen), eines Pluszeichens (dito), eines Minuszeichens (dito), eines Klein- oder Großbuchstabens E. Wenn ich irgendwelche Zeichen vergessen habe, die zur Bezeichnung einer Zahl verwendet werden können, geben Sie sie hier ein.
\s*,\s*
null oder mehr Leerzeichen, ein Komma, null oder mehr Leerzeichen
([0-9\.eE\+\-]+)
Gleicher Ausdruck wie beim ersten Bild. Es ist eine Referenz durch \2. Das Tolle ist: Sobald Sie so weit gekommen sind, können Sie aufhören. Es ist nicht erforderlich, die schließende Klammer oder Klammer zu erfassen (soweit ich das beurteilen kann). Du könntest, wenn du wolltest.
Alles in allem würde ich Bradys Lösung verwenden. Es ist prägnanter und leichter zu verstehen. Sie müssen das Komma zu den Trennzeichen hinzufügen, d. h.
"[(,])"
Betreff: Regex verwenden, um eckige Klammern zu findenIhr vorheriges Beispiel enthielt kein Leerzeichen nach dem Komma. Hier ist das korrigierte Skriptbeispiel:
Names Default to Here( 1 );
// source 1
string = "My spec limits are [0.080, 1.20] for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" ) );
Show( lsl, usl );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Show( lsl, usl );
// source 2
string = "My spec limits are (0.080, 1.20) for this CQA.";
// method 1: successive calls to Regex()
lsl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\1" ) );
usl = Num( Regex( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" ) );
Show( lsl, usl );
// method 2: one call to Regex Match, then convert items
limit = Regex Match( string, "(\d*\.?\d*),\D*(\d*\.?\d*)", "\2" );
lsl = Num( limit[2] );
usl = Num( limit[3] );
Show( lsl, usl );
Ich habe Ihre Datentabelle mit den korrigierten Formeln angehängt.
Betreff: Regex verwenden, um eckige Klammern zu findenDies ist ein gutes Beispiel dafür, wie schwierig die Implementierung von Regex sein kann, ohne die zugrunde liegenden Daten gut zu verstehen. Die Anwesenheit/Abwesenheit eines Raumes machte einen Unterschied.
Nehmen wir nun an, dass jedes legitime numerische Format unterstützt werden müsste. In diesem Fall würde die Regex hässlicher werden, da Sie die wissenschaftliche Schreibweise, Verneinungen, Punkte (oder auch nicht) usw. berücksichtigen müssten.
In solchen Fällen kann eine Kombination aus JSL-Funktionen und Regex die Aufgabe möglicherweise einfacher erledigen als beide allein.
Zum Beispiel in der JSL unten:
1) Ersetzen Sie Klammern und Klammern durch geschweifte Klammern (der Listenoperator ... wichtig in Punkt 3)
2) Regex erfasst die geschweiften Klammern und ihren Inhalt, wobei davon ausgegangen wird, dass es sich um ein Paar legitimer Zahlen in welchem Format auch immer handelt
3) Parse konvertiert die von Regex zurückgegebene Zeichenfolge in einen JSL-Ausdruck, der den Listeninhalt specLo und specHi zuweist.
txt = "My spec limits are [-4.087e-3, 1.20] for this CQA.";
{specLo, specHi} = Parse( Regex( Substitute( txt, "(", "{", "[", "{", ")", "}", "]", "}" ), "\\!{.*\\!}" ) );
-Brady
Betreff: Regex verwenden, um eckige Klammern zu findenVielen Dank für Ihre Hilfe!