正则表达式在花括号之间获取字符串


115

不幸的是,尽管尽我所能记住,尝试了一年至少一年一次的正则表达式学习,但我却经常忘记,因为我很少使用它们。今年,我新年的决心是不要再尝试学习正则表达式- 因此,今年,为了避免让我流泪,我将其交给Stack Overflow。(去年圣诞节混音)。

我想以这种格式传递一个字符串{getThis},然后返回该字符串getThis。有人能协助我们坚持我的新年决议吗?


有关堆栈溢出的相关问题:


5
该问题已添加到“高级Regex-Fu”下的“ 堆栈溢出正则表达式常见问题解答 ”中。
aliteralmind 2014年

@Kobi:常见问题解答是一个Wiki。任何人都可以编辑它。所以编辑它。
aliteralmind 2014年

Answers:


44

如果您的字符串将始终是该格式,则正则表达式会显得过大:

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

substring(1表示以一个字符开头(刚好超过第一个字符{),并且,g.length-1)表示以直到(但不包括)字符串长度减去一个字符为止。这是可行的,因为位置是从零开始的,即g.length-1最后一个位置。

对于比原来的海报其他读者:如果是一个正则表达式,使用/{([^}]*)}/,如果你想允许空字符串,或者/{([^}]+)}/如果你想只匹配时,有花括号之间至少有一个字符。分解:

  • /:启动正则表达式模式
    • {:大括号
      • (:开始捕获
        • [:开始定义要捕获的字符类
          • ^}:“除}”之外的任何东西
        • ]:好的,那是我们全班的定义
        • *:与我们刚定义的类相匹配的任意数量的字符
      • ):完成捕获
    • }:大括号必须立即跟随我们捕获的内容
  • /:结束正则表达式模式

7
子字符串化是根据您使用的语言而变化的事情之一。Javascript使用索引作为终止符,PHP使用所需最终结果的长度(除非它为负数,在这种情况下,它需要删除的字符数) ,C#又一次不同了……很好而且令人困惑。
jvenema 2010年

2
...而Python仅具有切片功能,而IMO比其他任何方法都好:p。
格兰特·保罗

27
很好,但是不确定如何使用正则表达式。也许他要求正则表达式,我来这里是相同的答案..可悲的答案无关与问题..
baash05

5
@ baash05,如果您阅读了整个问题,则OP甚至都不希望学习正则表达式,因此我认为这似乎并不是您建议的学术活动。
凯夫

2
我想做-1,因为这个问题是要求正则表达式,我正在寻找的正则表达式,但接受的答案对我来说完全无用的(而这个问题似乎很看好本身)。阅读第一条评论后,我必须承认,如果我要首先回答这个问题,我可能会以相同/相似的方式回答...所以最后,+ 1。
shadyyx 2014年

250

尝试

/{(.*?)}/

也就是说,匹配{和}之间的任何字符,但不要贪婪-匹配以}结尾的最短字符串(?停止*为贪婪)。括号使您可以提取匹配的部分。

另一种方式是

/{([^}]*)}/

这匹配除} char以外的任何字符(不贪婪的另一种方式)


这很好,但是可以在可变数量的花括号组合之间进行匹配吗?例如:“ {这应该被匹配}这不应该{这应该再次},然后{上}”?我想检索该值,该值不在大括号内。另外:句子中将不使用大括号,并且不会堆叠(这不会发生:“ {some {text}}”)。任何人都知道如何做到这一点:)?谢谢!(ps:支持该解决方案)
Igor,

4
它不会捕获大括号之间的所有内容,而是会捕获大括号和大括号本身之间的所有内容。您将如何只捕获大括号内的内容?
现实-洪流

1
我喜欢它,您不需要在这里花括号,因为regex解析器似乎意识到它们不是量词……好吧,我在python中这样做,但是我认为javascript regexes这样工作也是
drevicko '16

3
g在末尾添加a 使其成为全局搜索。参见工作示例
Benjamin

1
@ Reality-Torrent,如果我指定g选项来获取所有匹配项,我也看到它捕获了大括号。原来我应该在循环中使用Regex.exec而不是Javascript中的string.match来具有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 2012年

@Anil您似乎正在使用字符串作为拆分参数,而不是正则表达式。你想做什么?
meouw 2012年

30

试试这个:

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

例如

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

将返回gskinner.comssd.sd


1
太好了,您能解释一下为什么要\}在第一块中使用吗?
Uzair Ali,

1
不错,但它可以匹配以结尾的所有组},即使它不是以开头的{
艾哈迈德·易卜拉欣

1
这是实际可行的唯一正确答案。
pldg '18年

说明:尽管[^ \ {\}] +会匹配不包含花括号的所有内容,但超前断言(?=})将确保仅传递花括号之前的节。使用/ ... / g,我们可以得到所有的出现,而不仅仅是第一个。
0 -_- 0

19

这是使用javascript替换的简单解决方案

var st = '{getThis}';

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

正如上面公认的答案所指出的那样,原始问题很容易用子字符串解决,但是使用replace可以解决更复杂的用例

如果您有“ 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 2010年

这种方法有什么缺点?
Somatik

5
@Somatik-是的,ECMAScript不支持负向前和向后。
RobG

注意:此示例在Java中有效。返回所有花括号中的所有值。
Multiplexor

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
正是我想要的:)这将返回结果而不使用大括号,其他解决方案随之返回
Al-Mothafar

很好,最好的答案在这里。
michal.jakubeczy19年


4

我研究了其他答案,似乎没有一个重要的逻辑。即,选择两个CONSECUTIVE括号之间的所有内容,但不要选择括号

所以,这是我的答案

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

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

.replace(/.*{(.*)}.*/, '$1')不幸的是,如果正则表达式不匹配,则简单的返回整个字符串。上面的代码段可以更轻松地检测到匹配项。



2

您可以使用此正则表达式递归来匹配两者之间的所有内容,甚至另一个{}(例如JSON文本):

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

不错,但这只捕获了嵌套括号内的内容
Dominic

不捕获如果内容包含()
莫特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}]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.