Regex per ottenere una stringa tra parentesi graffe


115

Sfortunatamente, nonostante abbia provato a imparare le espressioni regolari almeno una volta all'anno per tutti gli anni che riesco a ricordare, me ne dimentico sempre perché le uso così di rado. Quest'anno il mio proposito per il nuovo anno è di non provare a imparare di nuovo le espressioni regolari - Quindi quest'anno per salvarmi dalle lacrime lo darò a Stack Overflow . (Last Christmas remix).

Voglio passare una stringa in questo formato {getThis}e ricevere la stringa getThis. Qualcuno potrebbe essere di aiuto per aiutarmi a rispettare i miei propositi per il nuovo anno?


Domande correlate su Stack Overflow:


5
Questa domanda è stata aggiunta alle domande frequenti sulle espressioni regolari di Stack Overflow , in "Advanced Regex-Fu".
aliteralmind

@Kobi: La FAQ è un wiki. Chiunque può modificarlo. Quindi modificalo.
aliteralmind

Risposte:


44

Se la tua stringa sarà sempre di quel formato, una regex è eccessiva:

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

substring(1significa iniziare un carattere in (appena dopo il primo {) e ,g.length-1)significa prendere caratteri fino a quando (ma non includendo) il carattere alla lunghezza della stringa meno uno. Questo funziona perché la posizione è a base zero, cioè g.length-1è l'ultima posizione.

Per lettori diversi dal poster originale: se deve essere una regex, usa /{([^}]*)}/se vuoi consentire stringhe vuote, o /{([^}]+)}/se vuoi trovare una corrispondenza solo quando c'è almeno un carattere tra le parentesi graffe. Abbattersi:

  • /: avvia il pattern regex
    • {: una parentesi graffa letterale
      • (: inizia a catturare
        • [: inizia a definire una classe di caratteri da catturare
          • ^}: "qualsiasi cosa diversa da }"
        • ]: OK, questa è la nostra intera definizione di classe
        • *: qualsiasi numero di caratteri corrispondente alla classe appena definita
      • ): cattura completata
    • }: una parentesi graffa letterale deve seguire immediatamente ciò che abbiamo catturato
  • /: termina il pattern regex

7
La sottostringa è una di quelle cose che cambia in base alla lingua in cui lavori. Javascript prende l'indice per fermarsi, PHP prende la lunghezza del risultato finale desiderato (a meno che non sia negativo, nel qual caso ci vuole il numero di caratteri da rimuovere) , C # è di nuovo diverso ... bello e confuso.
jvenema

2
... e Python ha solo lo slicing, che IMO è meglio di qualsiasi altra cosa: p.
Grant Paul

27
Dolce, ma non sono sicuro di come sia un'espressione regolare. Forse stava chiedendo
un'espressione regolare

5
@ baash05, se leggi l'intera domanda, l'OP non voleva nemmeno imparare le espressioni regolari, quindi non penso che sia l'esercizio accademico che sembri suggerire che fosse.
Kev

2
Volevo fare -1 perché la domanda sta chiedendo regex , stavo cercando regex , ma la risposta accettata era completamente inutile per me (mentre la domanda sembrava molto promettente). Dopo aver letto il primo commento devo ammettere che se avessi risposto prima a questa domanda avrei potuto rispondere nello stesso / simile modo ... Quindi, alla fine, +1.
shadyyx

250

Provare

/{(.*?)}/

Ciò significa che trova qualsiasi carattere tra {e}, ma non essere avido: trova la stringa più breve che termina con} (il? Smette * di essere avido). Le parentesi ti consentono di estrarre la parte corrispondente.

Un altro modo sarebbe

/{([^}]*)}/

Corrisponde a qualsiasi carattere eccetto un carattere} (un altro modo per non essere avido)


questo è eccellente, ma è possibile abbinare qualcosa tra un numero variabile di combinazioni di parentesi graffe? Ad esempio: "{this should be matched} this shouldnt {this kinda should again} and so {on}"? Vorrei recuperare il valore, che non è tra parentesi graffe. Inoltre: le parentesi graffe non verranno utilizzate nella frase e non vi è alcuna sovrapposizione (questo non si verificherebbe mai: "{some {text}}"). Qualcuno ha un'idea di come farlo :)? Grazie! (ps: votato per favore questa soluzione)
Igor

4
Non cattura tutto tra le parentesi graffe, cattura tutto ciò che si trova tra le parentesi graffe E le stesse parentesi graffe. Come faresti a catturare SOLO ciò che è all'interno delle parentesi graffe?
Reality-Torrent

1
Mi piace che non sia necessario sfuggire alle parentesi graffe qui poiché il parser delle espressioni regolari sembra rendersi conto che non sono un quantificatore ... beh, lo sto facendo in Python, ma presumo che le espressioni regolari di JavaScript funzionino così anche
drevicko

3
L'aggiunta di un galla fine ne fa una ricerca globale. Vedi un esempio funzionante
Benjamin il

1
@ Reality-Torrent, anch'io ho visto che ha catturato le parentesi graffe se specifico l'opzione g per ottenere tutte le corrispondenze. Risulta che dovrei usare Regex.exec in un ciclo invece di string.match in Javascript per avere sia il flag g che consentire il gruppo di cattura. Vedi developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
frank

150
/\{([^}]+)\}/

/        - 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 sa = s.split ("/ \ {([^}] +) \} /"); dà un errore di compilazione. ripetizione illegale, carattere di escape non valido.
likejudo

@Anil sembra che tu stia usando una stringa come argomento di divisione piuttosto che un'espressione regolare. Cosa stai cercando di fare?
meouw

30

Prova questo:

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

Per esempio

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

tornerà gskinner.com, ssd.sd.


1
Fantastico, puoi spiegare perché usi \}nel primo blocco?
Uzair Ali

1
Bello, ma corrisponderà a qualsiasi gruppo che finisce }, anche se non inizia con {.
Ahmad Ibrahim

1
Questa è l'unica risposta corretta che funziona davvero.
pldg

Spiegazione: sebbene [^ \ {\}] + corrisponda a tutto ciò che non è una parentesi graffa, l'asserzione lookahead (? =}) Farà in modo di passare solo le sezioni che precedono una parentesi graffa. Con / ... / g otteniamo tutte le occorrenze, non solo la prima.
0 -_- 0

19

Ecco una semplice soluzione utilizzando la sostituzione di javascript

var st = '{getThis}';

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

Come la risposta accettata sopra sottolinea il problema originale è facilmente risolvibile con la sottostringa, ma l'uso di sostituzione può risolvere i casi d'uso più complicati

Se hai una stringa come "randomstring999 [fieldname]", utilizzi un pattern leggermente diverso per ottenere fieldname

var nameAttr = "randomstring999[fieldname]";

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

15

Questo funziona in Textmate e corrisponde a tutto in un file CSS tra le parentesi graffe.

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

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

Se vuoi essere ulteriormente in grado di restituire il contenuto, racchiudi tutto in un altro set di parentesi in questo modo:

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

e puoi accedere ai contenuti tramite $ 1.

Funziona anche per le funzioni, ma non l'ho testato con parentesi graffe annidate.


14

Vuoi usare le espressioni regolari lookahead e lookbehind. Questo ti darà solo ciò che c'è dentro le parentesi graffe:

(?<=\{)(.*?)(?=\})

Dovrebbe esserci una barra rovesciata che sfugge alle parentesi graffe sopra. Sono stati spogliati nella mia sottomissione.
Robert Cesaric

1
Grazie, questo mi ha aiutato oggi.
ProfessionalAmateur

eventuali svantaggi di questo metodo?
Somatik

5
@ Somatik: sì, il lookahead negativo e quello successivo non sono supportati in ECMAScript.
RobG

Nota: questo esempio funziona in Java. Restituisce tutti i valori in tutte le parentesi graffe.
Multiplexor

13

Prova questo

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"]

1
Esattamente quello che volevo :) questo restituirà il risultato senza parentesi graffe, le altre soluzioni torneranno con esso
Al-Mothafar

Eccellente, la migliore risposta qui.
michal.jakubeczy

4

Regex per ottenere matrici di stringhe con parentesi graffe racchiuse si verifica in stringa, invece di trovare solo la prima occorrenza.

 /\{([^}]+)\}/gm 

4

Ho esaminato le altre risposte e sembra che manchi una logica vitale. cioè, seleziona tutto tra due parentesi CONSECUTIVE, ma NON le parentesi

quindi, ecco la mia risposta

\{([^{}]+)\}

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

Il più semplice .replace(/.*{(.*)}.*/, '$1')purtroppo restituisce l'intera stringa se la regex non corrisponde. Lo snippet di codice sopra può rilevare più facilmente una corrispondenza.



2

Puoi usare questa ricorsione regex per abbinare tutto, anche un altro {}(come un testo JSON):

\{([^()]|())*\}

Bello, ma questo cattura solo il contenuto all'interno di parentesi graffe nidificate
Dominic

non acquisisce se il contenuto contiene ()
Mert Mertce,

1

Anche questo mi aiuta mentre cerco di risolvere il problema di qualcuno,

Dividere il contenuto all'interno parentesi graffe ( {}) aventi un disegno tipo, {'day': 1, 'count': 100}.

Per esempio:

#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; 
}

Produzione:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.