Regex, um eine Schnur zwischen geschweiften Klammern zu erhalten

115

Leider vergesse ich immer, obwohl ich versucht habe, Regex mindestens einmal im Jahr so ​​viele Jahre lang zu lernen, wie ich mich erinnern kann, weil ich sie so selten benutze. In diesem Jahr ist mein Vorsatz für das neue Jahr, nicht noch einmal zu versuchen, Regex zu lernen. Um mich dieses Jahr vor Tränen zu bewahren, werde ich es Stack Overflow geben . (Letzter Weihnachts-Remix).

Ich möchte eine Zeichenfolge in diesem Format übergeben {getThis}und die Zeichenfolge zurückgeben getThis. Könnte jemand helfen, an meiner Neujahrsresolution festzuhalten?


Verwandte Fragen zum Stapelüberlauf:

ChrisInCambo
quelle
5
Diese Frage wurde in die häufig gestellten Fragen zum regulären Ausdruck des Stapelüberlaufs unter "Advanced Regex-Fu" aufgenommen.
Aliteralmind
@Kobi: Die FAQ ist ein Wiki. Jeder kann es bearbeiten. Also bearbeite es.
Aliteralmind

Antworten:

44

Wenn Ihre Zeichenfolge immer dieses Format hat, ist ein regulärer Ausdruck übertrieben:

>>> var g='{getThis}';
>>> g.substring(1,g.length-1)
"getThis"

substring(1bedeutet, ein Zeichen in (kurz nach dem ersten {) zu beginnen und ,g.length-1)Zeichen zu nehmen, bis das Zeichen die Zeichenfolgenlänge minus eins erreicht (aber nicht einschließt). Dies funktioniert, weil die Position auf Null basiert, dh g.length-1die letzte Position ist.

Für andere Leser als das Originalposter: Wenn es sich um eine Regex handeln muss, verwenden /{([^}]*)}/Sie diese Option, wenn Sie leere Zeichenfolgen zulassen möchten oder /{([^}]+)}/wenn Sie nur dann übereinstimmen möchten, wenn sich zwischen den geschweiften Klammern mindestens ein Zeichen befindet. Nervenzusammenbruch:

  • /: Starten Sie das Regex-Muster
    • {: eine buchstäblich geschweifte Klammer
      • (: Starten Sie die Aufnahme
        • [: Definieren Sie eine Klasse von Zeichen, die erfasst werden sollen
          • ^}: "alles andere als }"
        • ]: OK, das ist unsere gesamte Klassendefinition
        • *: eine beliebige Anzahl von Zeichen, die der gerade definierten Klasse entsprechen
      • ): aufgenommen
    • }: Eine buchstäblich geschweifte Klammer muss sofort dem folgen, was wir aufgenommen haben
  • /: Beenden Sie das Regex-Muster
Kev
quelle
7
Die Teilzeichenfolge ist eines der Dinge, die sich je nach der Sprache ändern, in der Sie arbeiten. Javascript verwendet den Index, um anzuhalten. PHP verwendet die Länge des gewünschten Endergebnisses (es sei denn, es ist negativ. In diesem Fall wird die Anzahl der zu entfernenden Zeichen benötigt.) , C # ist wieder anders ... nett und verwirrend.
Jvenema
2
... und Python hat nur Slicing, was IMO besser ist als alles andere: p.
Grant Paul
27
Süß, aber nicht sicher, wie das ein regulärer Ausdruck ist. Vielleicht hat er nach Regex gefragt, und ich bin wegen der gleichen Antwort hierher gekommen.
Leider
5
@ baash05, wenn Sie die ganze Frage lesen, wollte das OP nicht einmal Regex lernen, also denke ich nicht, dass es die akademische Übung ist, die Sie anscheinend vorschlagen.
Kev
2
Ich wollte -1 machen, weil die Frage nach Regex fragt , ich suchte nach Regex , aber die akzeptierte Antwort war für mich völlig nutzlos (während die Frage selbst sehr vielversprechend schien). Nachdem ich den ersten Kommentar gelesen habe, muss ich zugeben, dass ich, wenn ich diese Frage zuerst beantworten würde, auf die gleiche / ähnliche Weise hätte antworten können ... Also am Ende +1.
Shadyyx
250

Versuchen

/{(.*?)}/

Das heißt, passen Sie ein beliebiges Zeichen zwischen {und} an, aber seien Sie nicht gierig - passen Sie die kürzeste Zeichenfolge an, die mit} endet (das? Stoppt * ist gierig). Mit den Klammern können Sie den übereinstimmenden Teil extrahieren.

Ein anderer Weg wäre

/{([^}]*)}/

Dies entspricht jedem Zeichen außer einem} char (eine andere Art, nicht gierig zu sein)

Paul Dixon
quelle
Das ist ausgezeichnet, aber ist es möglich, irgendetwas zwischen einer variablen Anzahl von Curly-Bracket-Kombinationen abzugleichen? ZB: "{das sollte übereinstimmen} das sollte nicht {das sollte wieder sein} und so weiter}"? Ich möchte den Wert abrufen, der nicht in geschweiften Klammern steht. Außerdem: geschweifte Klammern werden im Satz nicht verwendet und es gibt keine Stapelung (dies würde niemals vorkommen: "{some {text}}"). Hat jemand eine Idee wie es geht :)? Vielen Dank! (ps: upvoted diese Lösung)
Igor
4
Es wird nicht alles zwischen den geschweiften Klammern erfasst, sondern alles zwischen den geschweiften Klammern UND den geschweiften Klammern selbst. Wie würden Sie NUR erfassen, was sich in den geschweiften Klammern befindet?
Reality-Torrent
1
Ich mag es, dass Sie den geschweiften Klammern hier nicht entkommen müssen, da der Regex-Parser zu erkennen scheint, dass sie kein Quantifizierer sind ... Nun, ich mache das in Python, aber ich gehe davon aus, dass Javascript-Regexe so funktionieren Auch
Drevicko
3
Das Hinzufügen von a gam Ende macht es zu einer globalen Suche. Sehen Sie ein Arbeitsbeispiel
Benjamin
1
@ Reality-Torrent, ich habe auch gesehen, dass es die geschweiften Klammern erfasst, wenn ich die Option g spezifiziere, um alle Übereinstimmungen zu erhalten. Es stellte sich heraus, dass ich Regex.exec in einer Schleife anstelle von string.match in Javascript verwenden sollte, um sowohl das g-Flag als auch die Erfassungsgruppe zuzulassen. Siehe developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Frank
149
/\{([^}]+)\}/

/        - delimiter
\{       - opening literal brace escaped because it is a special character used for quantifiers eg {2,3}
(        - start capturing
[^}]     - character class consisting of
    ^    - not
    }    - a closing brace (no escaping necessary because special characters in a character class are different)
+        - one or more of the character class
)        - end capturing
\}       - the closing literal brace
/        - delimiter
meouw
quelle
@meouw sa = s.split ("/ \ {([^}] +) \} /"); gibt einen Kompilierungsfehler aus. illegale Wiederholung, ungültiges Escapezeichen.
Likejudo
@Anil Sie scheinen eine Zeichenfolge als geteiltes Argument anstelle eines regulären Ausdrucks zu verwenden. Was versuchst du zu machen?
Meouw
30

Versuche dies:

/[^{\}]+(?=})/g

Beispielsweise

Welcome to RegExr v2.1 by #{gskinner.com},  #{ssd.sd} hosted by Media Temple!

wird zurückkehren gskinner.com, ssd.sd.

Mohamed Abo Elmagd
quelle
1
Großartig, können Sie erklären, warum Sie \}im ersten Block verwenden?
Uzair Ali
1
Schön, aber das }passt zu jeder Gruppe, die mit endet , auch wenn es nicht mit beginnt {.
Ahmad Ibrahim
1
Dies ist die einzig richtige Antwort, die tatsächlich funktioniert.
pldg
Erläuterung: Während [^ \ {\}] + mit allem übereinstimmt, was keine geschweifte Klammer ist, stellt die Lookahead-Zusicherung (? =}) Sicher, dass nur Abschnitte vor einer geschweiften Klammer übergeben werden. Mit / ... / g erhalten wir alle Vorkommen, nicht nur das erste.
0 -_- 0
19

Hier ist eine einfache Lösung mit Javascript ersetzen

var st = '{getThis}';

st = st.replace(/\{|\}/gi,''); // "getThis"

Wie die oben akzeptierte Antwort zeigt, lässt sich das ursprüngliche Problem leicht mit Teilzeichenfolgen lösen, aber die Verwendung von Ersetzen kann die komplizierteren Anwendungsfälle lösen

Wenn Sie eine Zeichenfolge wie "randomstring999 [Feldname]" haben, verwenden Sie ein etwas anderes Muster, um den Feldnamen abzurufen

var nameAttr = "randomstring999[fieldname]";

var justName = nameAttr.replace(/.*\[|\]/gi,''); // "fieldname"
chim
quelle
15

Dieser funktioniert in Textmate und passt alles in einer CSS-Datei zwischen den geschweiften Klammern an.

\{(\s*?.*?)*?\}

selector {. . matches here including white space. . .}

Wenn Sie den Inhalt weiter zurückgeben möchten, schließen Sie alles wie folgt in einen weiteren Satz Klammern ein:

\{((\s*?.*?)*?)\}

und Sie können über $ 1 auf den Inhalt zugreifen.

Dies funktioniert auch für Funktionen, aber ich habe es nicht mit verschachtelten geschweiften Klammern getestet.

Alex Kessaris
quelle
14

Sie möchten Regex Lookahead und Lookbehind verwenden. Dies gibt Ihnen nur das, was sich in den geschweiften Klammern befindet:

(?<=\{)(.*?)(?=\})
Robert Cesaric
quelle
Es sollte ein Backslash vorhanden sein, der aus den geschweiften Klammern oben austritt. Sie wurden in meiner Vorlage gestrippt.
Robert Cesaric
1
Danke, das hat mir heute geholfen.
ProfessionalAmateur
irgendwelche Nachteile dieser Methode?
Somatik
5
@ Somatik - Ja, negativer Lookahead und dahinter werden in ECMAScript nicht unterstützt.
RobG
Hinweis: Dieses Beispiel funktioniert in Java. Gibt alle Werte in geschweiften Klammern zurück.
Multiplexer
12

Versuche dies

let path = "/{id}/{name}/{age}";
const paramsPattern = /[^{\}]+(?=})/g;
let extractParams = path.match(paramsPattern);
console.log("extractParams", extractParams) // prints all the names between {} = ["id", "name", "age"]
Hemadri Dasari
quelle
1
Genau das, was ich wollte :) Dies wird das Ergebnis ohne geschweifte Klammern zurückgeben, die anderen Lösungen kehren damit zurück
Al-Mothafar
Ausgezeichnet, die beste Antwort hier.
michal.jakubeczy
4

Regex zum Abrufen von String-Arrays mit eingeschlossenen geschweiften Klammern tritt in String auf, anstatt nur das erste Vorkommen zu finden.

 /\{([^}]+)\}/gm 
Er. Mohit Agrawal
quelle
4

Ich habe mir die anderen Antworten angesehen, und eine wichtige Logik scheint in ihnen zu fehlen. Wählen Sie also alles zwischen zwei CONSECUTIVE-Klammern aus, aber NICHT die Klammern

Also, hier ist meine Antwort

\{([^{}]+)\}
Souparno Majumder
quelle
3
var re = /{(.*)}/;
var m = "{helloworld}".match(re);
if (m != null)
    console.log(m[0].replace(re, '$1'));

Der einfachere gibt .replace(/.*{(.*)}.*/, '$1')leider die gesamte Zeichenfolge zurück, wenn der reguläre Ausdruck nicht übereinstimmt. Das obige Codefragment kann eine Übereinstimmung leichter erkennen.

Curtis Yallop
quelle
3

Versuchen Sie dieses, laut http://www.regextester.com funktioniert es für js normal.

([^{]*?)(?=\})

Павло Коменда
quelle
3
für die Mehrfachauswahl können Sie verwenden /([^{]*?)\w(?=\})/gmi
23авло Коменда
2

Sie können diese Regex-Rekursion verwenden, um alles dazwischen abzugleichen, sogar eine andere {}(wie ein JSON-Text):

\{([^()]|())*\}
p3quod
quelle
Schön, aber dies erfasst nur den Inhalt in verschachtelten Klammern
Dominic
erfasst nicht, wenn der Inhalt enthält ()
Mert Mertce
1

Auch das hilft mir beim Versuch, jemandes Problem zu lösen.

Teilen Sie den Inhalt in geschweifte Klammern ( {}) mit einem Muster wie , {'day': 1, 'count': 100}.

Beispielsweise:

#include <iostream> 
#include <regex> 
#include<string> 
using namespace std; 

int main() 
{ 
    //string to be searched
    string s = "{'day': 1, 'count': 100}, {'day': 2, 'count': 100}";

    // regex expression for pattern to be searched 
    regex e ("\\{[a-z':, 0-9]+\\}");
    regex_token_iterator<string::iterator> rend;

    regex_token_iterator<string::iterator> a ( s.begin(), s.end(), e );
    while (a!=rend) cout << " [" << *a++ << "]";
    cout << endl;

    return 0; 
}

Ausgabe:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
Shudipta Sharma
quelle