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


116

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

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


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


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

4

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

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

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

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

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



2

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

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

Хорошо, но это захватывает только содержимое внутри вложенных фигурных скобок
Доминик

не захватывает, если контент содержит ()
Мерт Мертс

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.