【问题标题】:正则表达式查找包含在两个字符之间的字符串,同时排除分隔符
【发布时间】:2022-01-23 16:41:58
【问题描述】:

我需要从字符串中提取包含在两个分隔符之间的一组字符,而不返回分隔符本身。

一个简单的例子应该会有所帮助:

目标:提取方括号之间的子字符串,不返回括号本身。

基本字符串This is a test string [more or less]

如果我使用以下 reg.例如。

\[.*?\]

匹配是[more or less]。我只需要得到more or less(不带括号)。

有可能吗?

【问题讨论】:

标签: regex


【解决方案1】:

轻松搞定:

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

从技术上讲,这是使用前瞻和后瞻。见Lookahead and Lookbehind Zero-Width Assertions。该模式包括:

  • 前面有一个 [ 未捕获(后视);
  • 非贪婪捕获组。停在第一个 ] 是非贪婪的;和
  • 后跟一个未捕获的 ](前瞻)。

或者,您可以只捕获方括号之间的内容:

\[(.*?)\]

并返回第一个捕获的组而不是整个匹配项。

【讨论】:

  • “很简单”,哈哈! :) 正则表达式总是让我头疼,当我找到解决我问题的那些时,我往往会忘记它们。关于您的解决方案:第一个按预期工作,第二个没有,它一直包括括号。我正在使用 C#,也许 RegEx 对象有它自己的正则表达式引擎“风味”...
  • 这样做是因为您查看的是整场比赛而不是第一个匹配的组。
  • 如果子字符串也包含分隔符,这是否有效?例如在This is a test string [more [or] less] 中,这会返回more [or] less 吗?
  • @gnzlbg 不,它会返回“更多 [或”
  • 这将返回字符串以及开始和结束字符串
【解决方案2】:

如果您使用 JavaScript,cletus 提供的solution(?&lt;=\[)(.*?)(?=\]) 将不起作用,因为 JavaScript 不支持后向运算符。

编辑:实际上,now (ES2018) 可以使用后向运算符。只需添加 / 来定义正则表达式字符串,如下所示:

var regex = /(?<=\[)(.*?)(?=\])/;

旧答案

解决方案:

var regex = /\[(.*?)\]/;
var strToMatch = "This is a test string [more or less]";
var matched = regex.exec(strToMatch);

它会返回:

["[more or less]", "more or less"]

所以,您需要的是第二个值。使用:

var matched = regex.exec(strToMatch)[1];

返回:

"more or less"

【讨论】:

【解决方案3】:

您只需要“捕获”括号之间的位。

\[(.*?)\]

为了捕捉你把它放在括号内。你没有说这是使用哪种语言。例如,在 Perl 中,您可以使用 $1 变量来访问它。

my $string ='This is the match [more or less]';
$string =~ /\[(.*?)\]/;
print "match:$1\n";

其他语言会有不同的机制。例如,C# 使用 Match collection 类,我相信。

【讨论】:

  • 谢谢,但这个解决方案不起作用,它一直包含方括号。正如我在对 Cletus 解决方案的评论中所写,可能是 C# RegEx 对象对它的解释不同。虽然我不是 C# 专家,所以这只是一个猜想,也许只是我缺乏知识。 :)
【解决方案4】:

[^\[]匹配任何不是[的字符。

+ 匹配 1 个或多个不是 [ 的内容。创建这些匹配的组。

(?=\]) 正向前瞻]。匹配以] 结尾的组,但不包含在结果中。

完成。

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

证明。

http://regexr.com/3gobr

类似于null提出的解决方案。但不需要额外的\]。作为附加说明,\ 似乎不需要在 ^ 之后转义 [。为了可读性,我会把它留在里面。

在分隔符相同的情况下不起作用。以"more or less" 为例。

【讨论】:

  • 这是一个很好的解决方案,但是我做了一些调整,使它在最后也忽略了一个额外的 ']':[^\[\]]+(?=\])
【解决方案5】:

这是一个带有明显分隔符的一般示例(XY):

(?<=X)(.*?)(?=Y)

这里用于查找XY 之间的字符串。 Rubular 示例here,或见图片:

【讨论】:

    【解决方案6】:

    PHP:

    $string ='This is the match [more or less]';
    preg_match('#\[(.*)\]#', $string, $match);
    var_dump($match[1]);
    

    【讨论】:

      【解决方案7】:

      最新解决方案

      如果您使用的是 Javascript,我想出的最佳解决方案是使用 match 而不是 exec 方法。 然后,使用$1 迭代匹配并使用第一组的结果删除分隔符

      const text = "This is a test string [more or less], [more] and [less]";
      const regex = /\[(.*?)\]/gi;
      const resultMatchGroup = text.match(regex); // [ '[more or less]', '[more]', '[less]' ]
      const desiredRes = resultMatchGroup.map(match => match.replace(regex, "$1"))
      console.log("desiredRes", desiredRes); // [ 'more or less', 'more', 'less' ]
      

      如您所见,这对于文本中的多个分隔符也很有用

      【讨论】:

        【解决方案8】:

        要删除 [] 使用:

        \[.+\]
        

        【讨论】:

        【解决方案9】:

        这个特别适用于javascript的正则表达式解析器/[^[\]]+(?=])/g

        只需在控制台中运行它

        var regex = /[^[\]]+(?=])/g;
        var str = "This is a test string [more or less]";
        var match = regex.exec(str);
        match;
        

        【讨论】:

          【解决方案10】:

          我在使用带有 bash 脚本的正则表达式时遇到了同样的问题。 我使用带有 grep -o 应用的管道的两步解决方案

           '\[(.*?)\]'  
          

          先,然后

          '\b.*\b'
          

          显然在其他答案中效率不高,但可以替代。

          【讨论】:

            【解决方案11】:

            我想在 / 和 # 之间找到一个字符串,但 # 有时是可选的。这是我使用的正则表达式:

              (?<=\/)([^#]+)(?=#*)
            

            【讨论】:

              【解决方案12】:

              这是我在 C# 中没有 '['']' 的情况:

              var text = "This is a test string [more or less]";
              
              // Getting only string between '[' and ']'
              Regex regex = new Regex(@"\[(.+?)\]");
              var matchGroups = regex.Matches(text);
              
              for (int i = 0; i < matchGroups.Count; i++)
              {
                  Console.WriteLine(matchGroups[i].Groups[1]);
              }
              

              输出是:

              more or less
              

              【讨论】:

                【解决方案13】:

                如果需要提取不带括号的文本,可以使用 bash awk

                echo " [hola mundo] " | awk -F'[][]' '{print $2}'

                结果:

                hola mundo

                【讨论】:

                  猜你喜欢
                  • 2010-10-15
                  • 2020-06-20
                  • 1970-01-01
                  • 2022-01-18
                  • 2019-07-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多