Regex для получения строки между фигурными скобками

116

К сожалению, несмотря на то, что я пытался изучать регулярные выражения хотя бы раз в год в течение стольких лет, сколько я себя помню, я всегда забываю, поскольку использую их так редко. В этом году мое новогоднее решение - больше не пытаться выучить регулярное выражение - так что в этом году, чтобы спасти меня от слез, я отдам его на Stack Overflow . (Последний рождественский ремикс).

Я хочу передать строку в этом формате {getThis}и получить строку getThis. Может ли кто-нибудь помочь придерживаться моего новогоднего решения?


Связанные вопросы о переполнении стека:

ChrisInCambo
источник
5
Этот вопрос был добавлен в FAQ по регулярным выражениям при переполнении стека в разделе «Advanced 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 просто есть нарезка, что, по ИМО, лучше всего остального: p.
Грант Пол
27
Милый, но не знаю, как это регулярное выражение. Возможно, он просил регулярное выражение, и я пришел сюда за тем же ответом .. к сожалению, ответ не имеет ничего общего с вопросом ..
baash05
5
@ baash05, если вы прочитали весь вопрос, ОП даже не хотел изучать регулярное выражение, поэтому я не думаю, что это академическое упражнение, которое вы, похоже, предполагаете.
Кев
2
Я хотел сделать -1, потому что вопрос задает регулярное выражение , я искал регулярное выражение , но принятый ответ был для меня совершенно бесполезен (хотя сам вопрос казался очень многообещающим). После прочтения первого комментария я должен признать, что если бы я сначала ответил на этот вопрос, я бы ответил так же / аналогично ... Итак, в конце концов, +1.
shadyyx 04
250

Пытаться

/{(.*?)}/

Это означает, что сопоставьте любой символ между {и}, но не будьте жадными - сопоставьте самую короткую строку, которая заканчивается на} (? Перестает * быть жадным). Скобки позволяют извлечь совпавшую часть.

Другой способ был бы

/{([^}]*)}/

Соответствует любому символу, кроме символа} (еще один способ не жадничать)

Пол Диксон
источник
это отлично, но возможно ли сопоставить что-нибудь между переменным количеством комбинаций фигурных скобок? Например: "{это должно совпадать} этого не должно {это вроде должно снова} и так {далее}"? Я хочу получить значение, не заключенное в фигурные скобки. Также: фигурные скобки не будут использоваться в предложении и не будет складываться (это никогда не произойдет: "{some {text}}"). Кто-нибудь знает, как это сделать :)? Спасибо! (ps: проголосовал за это решение)
Игорь
4
Он не захватывает все, что находится между фигурными скобками, он захватывает все, что находится между фигурными скобками и самими фигурными скобками. Как бы вы записали ТОЛЬКО то, что находится внутри фигурных скобок?
Reality-Torrent
1
Мне нравится, что здесь вам не нужно избегать фигурных скобок, поскольку парсер регулярных выражений, кажется, понимает, что они не квантификатор ... ну, я делаю это на python, но я предполагаю, что регулярные выражения javascript работают так тоже
drevicko
3
Добавление gв конце делает его глобальным поиском. См. Рабочий пример
Benjamin
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
источник
@meouw sa = s.split ("/ \ {([^}] +) \} /"); дает ошибку компиляции. недопустимое повторение, недопустимый escape-символ.
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 02
Объяснение: Хотя [^ \ {\}] + будет соответствовать всему, что не является фигурной скобкой, утверждение просмотра вперед (? =}) Гарантирует, что передаются только те разделы, которые предшествуют фигурной скобке. С помощью / ... / g мы получаем все вхождения, а не только первое.
0 -_- 0
20

Вот простое решение с использованием замены javascript

var st = '{getThis}';

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

Как указано в принятом ответе выше, исходная проблема легко решается с помощью подстроки, но использование замены может решить более сложные варианты использования.

Если у вас есть строка типа "randomstring999 [fieldname]", вы используете немного другой шаблон для получения fieldname.

var nameAttr = "randomstring999[fieldname]";

var justName = nameAttr.replace(/.*\[|\]/gi,''); // "fieldname"
Хим
источник
15

Этот работает в Textmate и соответствует всему в файле CSS между фигурными скобками.

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

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

Если вы хотите в дальнейшем иметь возможность возвращать контент, заключите все это в еще один набор круглых скобок, например так:

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

и вы можете получить доступ к содержимому через $ 1.

Это также работает для функций, но я не тестировал его с вложенными фигурными скобками.

Алекс Кессарис
источник
14

Вы хотите использовать регулярное выражение вперед и назад. Это даст вам только то, что находится внутри фигурных скобок:

(?<=\{)(.*?)(?=\})
Роберт Сезарик
источник
Вместо фигурных скобок выше должна быть обратная косая черта. В моем представлении они были вырезаны.
Роберт Сезарик
1
Спасибо, это помогло мне сегодня.
ProfessionalAmateur
какие недостатки у этого метода?
Somatik
5
@ Somatik - да, отрицательный просмотр вперед и назад не поддерживается в ECMAScript.
RobG
Примечание. Этот пример работает на Java. Возвращает все значения во всех фигурных скобках.
Мультиплексор
14

Попробуй это

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

Регулярное выражение для получения массивов строк с заключенными в фигурные скобки происходит в строке, а не просто для поиска первого вхождения.

 /\{([^}]+)\}/gm 
Er. Мохит Агравал
источник
4

Я просмотрел другие ответы, и, похоже, в них отсутствует жизненная логика. т.е. выберите все между двумя ПОСЛЕДУЮЩИМИ скобками, но НЕ скобки

Итак, вот мой ответ

\{([^{}]+)\}
супарно мажумдер
источник
3
var re = /{(.*)}/;
var m = "{helloworld}".match(re);
if (m != null)
    console.log(m[0].replace(re, '$1'));

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

Кертис Яллоп
источник
3

Попробуйте это, согласно http://www.regextester.com, он работает для js нормально.

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

Павло Коменда
источник
3
для множественного выбора можно использовать /([^{]*?)\w(?=\})/gmi
Павло Коменда
2

Вы можете использовать эту рекурсию регулярных выражений для сопоставления всего, даже другого {}(например, текста JSON):

\{([^()]|())*\}
p3quod
источник
Хорошо, но это захватывает только содержимое внутри вложенных фигурных скобок
Доминик
не захватывает, если контент содержит ()
Мерт Мертс
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}]
Шудипта Шарма
источник