【问题标题】:Regular expression to extract text between square brackets正则表达式提取方括号之间的文本
【发布时间】:2011-01-25 01:52:10
【问题描述】:

简单的正则表达式问题。我有以下格式的字符串:

this is a [sample] string with [some] special words. [another one]

提取方括号内的单词的正则表达式是什么,即。

sample
some
another one

注意:在我的用例中,括号不能嵌套。

【问题讨论】:

    标签: regex


    【解决方案1】:

    您可以全局使用以下正则表达式:

    \[(.*?)\]
    

    解释:

    • \[ : [ 是一个元字符,如果你想从字面上匹配,需要转义。
    • (.*?) :以非贪婪的方式匹配所有内容并捕获它。
    • \] : ] 是一个元字符,如果你想从字面上匹配,需要转义。

    【讨论】:

    • 另一个答案的方法,使用[^]] 比非贪婪(?)更快,并且也适用于不支持非贪婪的正则表达式风格。但是,非贪婪看起来更好。
    • 如何从输出(结果)中排除[ ]
    • @MickeyTin,如果你使用的是 Java,你可以使用 group(1) 而不是 group() 进行分组,这样 '[]' 就不会在一起了
    • 这只匹配第一次出现
    • 如何从 return 中排除括号?
    【解决方案2】:
    (?<=\[).+?(?=\])
    

    将捕获不带括号的内容

    • (?&lt;=\[) - [ 的正向回溯

    • .*? - 内容的非贪婪匹配

    • (?=\]) - ] 的正向前瞻

    编辑:对于嵌套括号,下面的正则表达式应该可以工作:

    (\[(?:\[??[^\[]*?\]))
    

    【讨论】:

    • @igaurav 我已经检查过了,它可以工作。但是,它在不支持像 Javascript 之类的lookbehinds 的环境中不起作用。也许这就是你的情况?
    • 亚当,当有一个带有. 的字符串时,您的嵌套括号解决方案将失败...
    • 写这些正则表达式的人你是该死的魔术师。非常感谢!
    • 这应该是公认的答案,因为提问者指定了不带括号的输出。当前接受的答案将返回[ '[sample]', '[some]', '[another one]' ],而此答案将返回[ 'sample', 'some', 'another one' ]
    • 并非所有浏览器都支持“正向后视”功能。
    【解决方案3】:

    这应该没问题:

    \[([^]]+)\]
    

    【讨论】:

    • 在我的用例中,括号中的文本可能包含新行,并且此正则表达式有效,而接受的答案则无效。
    • 字符类 [^]] 是什么意思?它匹配什么?
    • @Richard,^ 否定字符类。它的意思是“任何不是]的字符”。
    • 我认为它没有按预期工作,您应该使用\[([^\[\]]*)\] 来获取最内括号中的内容。如果您查看lfjlksd [ded[ee]22],那么\[([^]]+)\] 将得到[ded[ee],而建议的表达式将返回[ee]。在link进行测试
    • 您能否提供“sed”和“awk”示例以使用此正则表达式并提取文本。谢谢。
    【解决方案4】:

    括号可以嵌套吗?

    如果不是:\[([^]]+)\] 匹配一项,包括方括号。反向引用\1 将包含要匹配的项目。如果您的正则表达式支持环视,请使用

    (?<=\[)[^]]+(?=\])
    

    这只会匹配括号内的项目。

    【讨论】:

    • @KunalMukherjee:不,正则表达式可以匹配任意次数。但是需要明确告知某些正则表达式风格以重复应用正则表达式(例如,通过在 JavaScript 中使用 /g 标志)。
    【解决方案5】:

    如果您不想在匹配中包含括号,请使用正则表达式:(?&lt;=\[).*?(?=\])

    让我们分解一下

    . 匹配除行终止符之外的任何字符。 ?= 是一个正向预测。当某个字符串紧随其后时,正向先行会找到一个字符串。 ?&lt;=积极的后视。当某个字符串位于某个字符串之前时,正向向后查找会找到一个字符串。引用this

    向前看积极 (?=)

    在表达式 B 的后面找到表达式 A:

    A(?=B)

    往后看正面 (?

    在表达式 B 中找到表达式 A 前面:

    (?&lt;=B)A

    另一种选择

    如果您的正则表达式引擎不支持前瞻和后瞻,那么您可以使用正则表达式 \[(.*?)\] 捕获组中括号的内部信息,然后您可以根据需要操作该组。

    这个正则表达式是如何工作的?

    括号捕获组中的字符。 .*? 以不贪婪的方式获取括号之间的所有字符(行终止符除外,除非您启用了 s 标志)。

    【讨论】:

      【解决方案6】:

      要匹配first [last ] 之间的子字符串,您可以使用

      \[.*\]            # Including open/close brackets
      \[(.*)\]          # Excluding open/close brackets (using a capturing group)
      (?<=\[).*(?=\])   # Excluding open/close brackets (using lookarounds)
      

      查看regex demoregex demo #2

      使用以下表达式匹配最接近方括号之间的字符串:

      • 包括括号:

      • \[[^][]*] - PCRE、Python re/regex、.NET、Golang、POSIX(grep、sed、bash)

      • \[[^\][]*] - ECMAScript(JavaScript,C++ std::regex,VBA RegExp

      • \[[^\]\[]*] - Java、ICU 正则表达式

      • \[[^\]\[]*\] - Onigmo(Ruby,需要到处转义括号)

      • 不包括括号:

      • (?&lt;=\[)[^][]*(?=]) - PCRE、Python re/regex、.NET(C# 等)、JGSoft 软件

      • \[([^][]*)] - Bash, Golang - 捕获方括号之间的内容用一对未转义的括号,另见下文

      • \[([^\][]*)] - JavaScript, C++ std::regex, VBA RegExp

      • (?&lt;=\[)[^\]\[]*(?=]) - Java 正则表达式,ICU (R stringr)

      • (?&lt;=\[)[^\]\[]*(?=\]) - Onigmo(Ruby,需要到处转义括号)

      注意* 匹配 0 个或多个字符,使用 + 匹配 1 个或多个字符以避免结果列表/数组中出现空字符串匹配。

      只要两种环视支持都可用,上述解决方案依赖它们来排除前导/尾随打开/关闭括号。否则,请依靠捕获组(已提供某些语言的最常见解决方案的链接)。

      如果您需要匹配嵌套括号,您可以在Regular expression to match balanced parentheses 线程中查看解决方案并将圆括号替换为方括号以获得必要的功能。您应该使用捕获组来访问排除开/关括号的内容:

      【讨论】:

      • 这个\[((?&gt;[^][]+|(?&lt;o&gt;)\[|(?&lt;-o&gt;]))*)] 是我需要的 99.9%。我的意思是我需要最外面的括号内的所有内容,而不是括号本身。 IE,在您的 .Net 演示链接中,它匹配所有 [text [2]],我希望匹配返回“text [2]”。但是,我可以通过匹配并执行一个跳过第一个和最后一个字符的简单子字符串来解决这个问题。我很好奇是否可以稍微修改该正则表达式以自动省略最外面的括号。
      • @B.O.B.您需要获取第 1 组的值,请参阅the C# demo online
      • 谢谢!我将尝试在我正在使用的演示代码中进行尝试(在将其移入实际项目之前)。编辑:就是这样!感谢专家和异常快速的响应)。
      【解决方案7】:

      (?&lt;=\[).*?(?=\]) 按照上面给出的解释工作得很好。这是一个 Python 示例:

      import re 
      str = "Pagination.go('formPagination_bottom',2,'Page',true,'1',null,'2013')"
      re.search('(?<=\[).*?(?=\])', str).group()
      "'formPagination_bottom',2,'Page',true,'1',null,'2013'"
      

      【讨论】:

      • 您应该始终对正则表达式使用代码格式,无论它们出现在哪里。如果正则表达式在文本中而不是代码块中,您可以使用反引号来格式化它们。 (ref)
      • 另外,问题是关于方括号 ([]),而不是括号。
      【解决方案8】:

      以防万一,你可能有unbalanced brackets,你可以设计一些类似于递归的表达式,

      \[(([^\]\[]+)|(?R))*+\]
      

      当然,这与您可能使用的语言或 RegEx 引擎有关。

      RegEx Demo 1


      除此之外,

      \[([^\]\[\r\n]*)\]
      

      RegEx Demo 2

      或者,

      (?<=\[)[^\]\[\r\n]*(?=\])
      

      RegEx Demo 3

      是探索的好选择。


      如果您希望简化/修改/探索表达式,在regex101.com 的右上角面板中已对此进行了说明。如果您愿意,您还可以在this link 中观看它如何与一些示例输入匹配。


      正则表达式电路

      jex.im 可视化正则表达式:

      测试

      const regex = /\[([^\]\[\r\n]*)\]/gm;
      const str = `This is a [sample] string with [some] special words. [another one]
      This is a [sample string with [some special words. [another one
      This is a [sample[sample]] string with [[some][some]] special words. [[another one]]`;
      let m;
      
      while ((m = regex.exec(str)) !== null) {
          // This is necessary to avoid infinite loops with zero-width matches
          if (m.index === regex.lastIndex) {
              regex.lastIndex++;
          }
          
          // The result can be accessed through the `m`-variable.
          m.forEach((match, groupIndex) => {
              console.log(`Found match, group ${groupIndex}: ${match}`);
          });
      }

      来源

      Regular expression to match balanced parentheses

      【讨论】:

        【解决方案9】:

        @Tim Pietzcker 的回答 here

        (?<=\[)[^]]+(?=\])
        

        几乎是我一直在寻找的那个。但是有一个问题是一些旧版浏览器可能会在积极的后视中失败。 所以我不得不自己过日子:)。我设法写了这个:

        /([^[]+(?=]))/g
        

        也许它会对某人有所帮助。

        console.log("this is a [sample] string with [some] special words. [another one]".match(/([^[]+(?=]))/g));

        【讨论】:

        • 我正在寻找的完美答案
        • 狡猾的瑞克!很好地很好地使用了运行代码 sn-p 来展示它是如何工作的。很好的答案。
        【解决方案10】:

        此代码将提取方括号和括号之间的内容

        (?:(?<=\().+?(?=\))|(?<=\[).+?(?=\]))
        
        (?: non capturing group
        (?<=\().+?(?=\)) positive lookbehind and lookahead to extract the text between parentheses
        | or
        (?<=\[).+?(?=\]) positive lookbehind and lookahead to extract the text between square brackets
        

        【讨论】:

          【解决方案11】:

          在 R 中,尝试:

          x <- 'foo[bar]baz'
          str_replace(x, ".*?\\[(.*?)\\].*", "\\1")
          [1] "bar"
          

          【讨论】:

          • ..或gsub(pat, "\\1", x, perl=TRUE),其中pat是您提供的正则表达式..
          • 这个解决方案非常棒,它“提取”括号内的内容如果有,否则你会得到输入。
          【解决方案12】:

          如果您只想在方括号 a-z 之间填充小字母

          (\[[a-z]*\])
          

          如果你想要小写和大写字母 a-zA-Z

          (\[[a-zA-Z]*\]) 
          

          如果您想要小写字母和数字字母 a-zA-Z0-9

          (\[[a-zA-Z0-9]*\]) 
          

          如果你想要方括号之间的所有内容

          如果你想要文字、数字和符号

          (\[.*\])
          

          【讨论】:

            【解决方案13】:
            ([[][a-z \s]+[]])
            

            上面的解释应该可以工作

            • 方括号[] 中的字符定义字符类,这意味着模式应与方括号中提到的至少一个字符匹配

            • \s 指定空格

            •  + 表示前面提到的至少一个 + 字符。

            【讨论】:

            • 在敏感情况下A-Z 应该添加到模式中:([[][a-zA-Z \s]+[]]);我认为这是一个好方法,而 \ 在正则表达式模式中定义字符串标记( " 和 ' )并通过 " 或 ' 用法中的反斜杠处理来混合新手!
            • 唯一对我有用的 C++ 正则表达式的答案(除了我用引号而不是括号来做)。 std::regex pattern{R"(["][a-zA-Z \s]+["])"};
            【解决方案14】:

            我需要包括换行符和括号

            \[[\s\S]+\]

            【讨论】:

              【解决方案15】:

              如果有人想要匹配并选择一个包含一个或多个在方括号内的点的字符串,例如“[fu.bar]”,请使用以下命令:

              (?<=\[)(\w+\.\w+.*?)(?=\])
              

              Regex Tester

              【讨论】: