Regex, щоб отримати рядок між фігурними дужками


115

На жаль, незважаючи на те, що я намагався навчитися регексу принаймні один раз на рік протягом стількох років, наскільки я пам'ятаю, я завжди забуваю, оскільки використовую їх так рідко. Цього року моя новорічна резолюція полягає в тому, щоб не намагатися знову вивчити регекс - Тому цього року, щоб врятувати мене від сліз, я дам його Stack Overflow . (Останній різдвяний ремікс).

Я хочу передати рядок у такому форматі {getThis}та повернутись рядок getThis. Чи може хтось допомогти у дотриманні моєї новорічної резолюції?


Пов’язані запитання щодо переповнення стека:


5
Це запитання було додано до поширених запитань щодо регулярного вираження стека в розділі "Розширений Regex-Fu".
aliteralmind

@Kobi: FAQ - це вікі. Редагувати його може будь-хто. Тож відредагуйте.
aliteralmind

Відповіді:


44

Якщо ваш рядок завжди буде у такому форматі, регулярний вираз є надмірним:

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

substring(1означає запустити один символ (просто минулий перший {) і ,g.length-1)означає взяти символи до (але не включаючи) символу довжиною рядка мінус один. Це працює, оскільки позиція заснована на нулі, тобто g.length-1є останньою позицією.

Для інших оригінального плакату читачів: Якщо це має бути регулярним виразом, використання , /{([^}]*)}/якщо ви хочете , щоб порожні рядки, або /{([^}]+)}/якщо ви хочете , щоб відповідати тільки , коли є принаймні один символ між фігурними дужками. Зламатися:

  • /: запустити схему регулярного вираження
    • {: буквальна фігурна дужка
      • (: почати захоплення
        • [: почати визначати клас символів для захоплення
          • ^}: "нічого, крім }"
        • ]: Гаразд, це все наше визначення класу
        • *: будь-яка кількість символів, що відповідає тому класу, який ми тільки що визначили
      • ): зроблено захоплення
    • }: буквальна фігурна дужка повинна негайно слідувати тому, що ми захопили
  • /: закінчити шаблон регулярного виразка

7
Підрядка - це одна з тих речей, яка змінюється залежно від мови, на якій ви працюєте. Javascript приймає індекс, на якому зупиняється, PHP приймає довжину бажаного кінцевого результату (якщо він не є негативним; у цьому випадку потрібно видалити кількість символів) , C # знову відрізняється ... приємно і заплутано.
jvenema

2
... і Python просто має нарізку, яка IMO краща за все: p.
Грант Пол

27
Солодкий, але не впевнений, як це регулярний вираз. Можливо, він просив regex, і я прийшов сюди за тією ж відповіддю .., на жаль, відповідь не має нічого спільного з питанням ..
baash05

5
@ baash05, якщо ви прочитали ціле запитання, ОП навіть не хотів вивчати регулярні вирази, тому я не думаю, що ви, начебто, пропонуєте це зробити.
Кев

2
Я хотів зробити -1, тому що питання просить регулярного вираження , я шукав регулярний вираз , але прийнята відповідь була для мене абсолютно марною (в той час як питання здавалося дуже перспективним). Прочитавши перший коментар, я повинен визнати, що якби я спершу відповів на це запитання, я міг би відповісти тим самим / подібним чином ... Отже, врешті-решт, +1.
shadyyx

250

Спробуйте

/{(.*?)}/

Це означає, що порівнюйте будь-які символи між {і}, але не будьте жадібними - відповідність найкоротшій рядку, що закінчується на} (? Перестає * бути жадібним). В дужках ви можете витягнути відповідну частину.

Інший спосіб був би

/{([^}]*)}/

Це відповідає будь-якому персонажу, крім} char (інший спосіб не бути жадібним)


це чудово, але чи можна зіставити що-небудь між змінною кількістю комбінацій фігурних дужок? Напр .: "{це має відповідати} це не повинно {це щось знову повинно} і так {на}"? Я хотів би отримати значення, яке не в фігурних дужках. Також: фігурні дужки не будуть використані у реченні, і немає складання (це ніколи не виникне: "{some {text}}"). У когось ідея, як це зробити :)? Дякую! (ps: підтримали це рішення)
Ігор

4
Він не фіксує все між фігурними дужками, він фіксує все між фігурними дужками І самими фігурними дужками. Як би Ви хотіли ТОЛЬКО фіксувати те, що знаходиться всередині фігурних дужок?
реальність-торрент

1
Мені подобається, що вам не потрібно уникати фігурних дужок тут, оскільки аналізатор регулярних виразів, здається, усвідомлює, що вони не є кількісним показником ... ну, я роблю це в python, але я припускаю, що реджекси JavaScript працюють так теж
drevicko

3
Додавання в gкінці робить це глобальним пошуком. Дивіться робочий приклад
Бенджамін

1
@ Reality-Torrent, я теж бачив, що він захоплював фігурні дужки, якщо я вказав опцію g, щоб отримати всі збіги. Виявляється, я повинен використовувати Regex.exec в циклі замість string.match в Javascript, щоб мати як прапор g, так і можливість захоплення групи. Дивіться developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
відвертий

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 ("/ \ {([^}] +) \} /"); дає помилку компіляції. незаконне повторення, недійсний характер втечі.
likejudo

@Anil, здається, ви використовуєте рядок як розділений аргумент, а не регулярний вираз. Що ви намагаєтесь зробити?
meouw

30

Спробуйте це:

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

Наприклад

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

повернеться gskinner.com, ssd.sd.


1
Чудово, ви можете пояснити, чому ви використовуєте \}в першому блоці?
Узаїр Алі

1
Хороший, але це буде відповідати будь-якій групі, яка закінчується }, навіть якщо вона не починається {.
Ахмад Ібрагім

1
Це єдина правильна відповідь, яка насправді працює.
pldg

Пояснення: Хоча [^ \ {\}] + відповідатиме будь-чому, що не є фігурною дужкою, твердження lookahead (? =}) Обов'язково передасть лише розділи, що передують фігурній дужці. З / ... / г ми отримуємо всі події, не тільки перші.
0 -_- 0

19

Ось просте рішення за допомогою JavaScript заміни

var st = '{getThis}';

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

Як зазначено у прийнятій відповіді вище, оригінальну проблему легко вирішити за допомогою підрядка, але за допомогою заміни можна вирішити і складніші випадки використання

Якщо у вас є рядок типу "randomstring999 [ім'я поля]", ви використовуєте трохи інший шаблон для отримання імені поля

var nameAttr = "randomstring999[fieldname]";

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

15

Цей працює в Textmate і відповідає всім файлам CSS між фігурними дужками.

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

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

Якщо ви хочете надалі мати змогу повернути вміст, загорніть його в ще один набір дужок, як-от так:

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

і ви можете отримати доступ до вмісту через $ 1.

Це також працює для функцій, але я не перевіряв його з вкладеними фігурними дужками.


14

Ви хочете використовувати regex lookahead і дивитися позаду. Це дасть вам лише те, що знаходиться всередині фігурних брекетів:

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

Повинна бути зворотна косою рисою, що уникає фігурних дужок зверху. Вони були позбавлені моїх подань.
Роберт Сезарік

1
Дякую, це мені сьогодні допомогло.
ProfessionalAmateur

якісь недоліки цього методу?
Соматік

5
@ Somatik - так, негативний пошук і позаду не підтримуються в ECMAScript.
RobG

Примітка. Цей приклад працює в Java. Повертає всі значення у всіх фігурних дужках.
Мультиплексор

13

Спробуйте це

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
Саме те, що я хотів :), це поверне результат без дужок, інші рішення повертаються разом з ним
Аль-Мотафар

Відмінна, найкраща відповідь тут.
michal.jakubeczy

4

Regex для отримання масивів рядків із фігурними фігурними дужками укладений у рядку, а не просто знаходження першої зустрічі.

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

4

я переглянув інші відповіді, і життєва логіка, здається, у них відсутня. тобто виберіть все між двома КОНСУКТИВНИми дужками, але НЕ дужками

Отже, ось моя відповідь

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

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

Простіший, .replace(/.*{(.*)}.*/, '$1')на жаль, повертає весь рядок, якщо регулярний вираз не відповідає. Вищенаведений фрагмент коду може легше виявити відповідність.



2

Ви можете використовувати цю регекс-рекурсію, щоб відповідати між собою, навіть іншим {}(як текст JSON):

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

Приємно, але це лише фіксує вміст всередині вкладених брекетів
Домінік

не захоплює, якщо вміст містить ()
Mert Mertce

1

Навіть це допомагає мені, намагаючись вирішити чиюсь проблему,

Розділити вміст всередині фігурних дужок ( {}) , який має малюнок , як, {'day': 1, 'count': 100}.

Наприклад:

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

Вихід:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.