Regex 使用正则表达式搜索文本以匹配外部特定字符

Regex 使用正则表达式搜索文本以匹配外部特定字符,regex,Regex,我的文本看起来像: 我的名字是(理查德),我做不到 [不管(杰克)做不了什么]和 (罗伯特)也是这样[不像 (贝蒂)谢谢(吉尔) 目标是使用正则表达式搜索,以查找文本中任何位置出现但位于任何括号之间的所有括号内的名称 因此,在上面的文本中,我想要的结果是: 理查德 罗伯特 吉尔 对于单个regexp来说,这并不是最好的工作-例如,您是否考虑过复制字符串,然后删除方括号中的所有内容?然后,从括号内提取内容就相当简单了。或者,您可以编写一个非常基本的解析器来标记该行(我想是普通文本、方括号文本和括

我的文本看起来像:

我的名字是(理查德),我做不到 [不管(杰克)做不了什么]和 (罗伯特)也是这样[不像 (贝蒂)谢谢(吉尔)

目标是使用正则表达式搜索,以查找文本中任何位置出现但位于任何括号之间的所有括号内的名称

因此,在上面的文本中,我想要的结果是:

  • 理查德
  • 罗伯特
  • 吉尔

    • 对于单个regexp来说,这并不是最好的工作-例如,您是否考虑过复制字符串,然后删除方括号中的所有内容?然后,从括号内提取内容就相当简单了。或者,您可以编写一个非常基本的解析器来标记该行(我想是普通文本、方括号文本和括号文本),然后解析生成该行的树;一开始会有更多的工作,但如果你以后想让行为变得更复杂,会让生活更简单

      话虽如此,
      /(?:(?:^ |\])[^\[]*)\(.*?)/
      为您的测试用例提供了窍门(但如果您的
      [
      ]
      没有正确匹配,几乎肯定会有一些奇怪的行为,而且我不相信它有这么高的效率)

      一个快速(PHP)测试用例:

      preg_match_all('/(?:(?:^|\])[^\[]*)\((.*?)\)/', "My name is ... (Jill)", $m);
      
      print(implode(", ", $m[1]));
      产出:

      Richard, Robert, Jill
      Richard、Robert、Jill你可以分两步完成:

      步骤1:使用以下方法匹配所有括号内容:

      \[[^\]]*\]
      
      并将其替换为
      '

      步骤2:使用以下方法(全局)匹配所有剩余括号中的名称:


      如果您正在使用.NET,您可以执行以下操作:

      "(?<!\[.*?)(?<name>\(\w+\))(?>!.*\])"
      
      “(?\(\w+\)(?>!.\])”
      
      您没有说您使用的是什么语言,所以这里有一些Python:

      >>> import re
      >>> REGEX = re.compile(r'(?:[^[(]+|\(([^)]*)\)|\[[^]]*])')
      >>> s="""My name is (Richard) and I cannot do [whatever (Jack) can't do] and (Robert) is the same way [unlike (Betty)] thanks (Jill)"""
      >>> filter(None, REGEX.findall(s))
      
      输出为:

      ['Richard', 'Robert', 'Jill']
      
      一个警告是,这不适用于任意嵌套。它真正设计用来处理的唯一嵌套是问题中提到的方括号中的一级排列。仅使用正则表达式无法完成任意嵌套。(这是一个结果。)


      正则表达式查找没有括号或括号的文本块、括号中包含的文本块以及括号中包含的文本块。仅捕获括号中的文本(不在方括号中)。Python的
      findall
      按顺序查找正则表达式的所有匹配项。在某些语言中,可能需要编写循环以重复匹配。对于非paren匹配,
      findall
      在结果列表中插入一个空字符串,因此对
      filter
      的调用将删除这些字符串。

      那么您希望正则表达式与名称匹配,而不是与括号匹配?这应该做到:

      [^()]+(?=\)[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*$)
      
      和其他答案一样,我对目标字符串做了一些假设,比如期望括号和方括号正确平衡,而不是嵌套


      我说它应该可以工作,因为尽管我已经测试过它,但我不知道您使用什么语言/工具来匹配正则表达式。如果我们有这些信息,我们可以提供更高质量的答案;并非所有正则表达式的风格都是相同的。

      这难道不能将Robert从示例中挑选出来吗?后面的查找将找到包含Jack的
      [
      ,前面的查找将找到Betty的
      ]
      。.s需要替换为
      [^\]
      [^\[]
      我猜是分别的。一些正则表达式引擎也不支持非固定宽度的负向后看。这是一种负向前看和向后看。我知道这一点。再想一想,我认为这将无法从输入中选择任何名称-你真的尝试过吗?;)对于除Richard以外的所有名称,负向后看将导致e匹配失败(因为
      \[.*?
      可以很容易地匹配到所有其他名称的开头),对于除吉尔以外的所有人来说,消极的前瞻将导致它失败,原因类似。@Chris是对的:它不能按原样工作,在做了更改后,他建议它只能在.NET或JGSoft(EditPad Pro、PowerGrep等)中工作,因为它们是唯一支持无限前视的风格。而且,你的否定前视语法也错了。:-/@Paulo Santos:我不知道人们是否会“忘记”保罗:我们中的一些人只是希望我们能够忘记它们。P lookbehind(特别是lookbehind)比许多人期望的要复杂得多,也没那么有用。是的,你可以,但是不会有那么多乐趣吧?
      ['Richard', 'Robert', 'Jill']
      
      [^()]+(?=\)[^\[\]]*(?:\[[^\[\]]*\][^\[\]]*)*$)