正则表达式,用于在括号内包含文本的括号之间获取文本

时间:2013-07-03 03:24:29

标签: php regex

尝试10次重写这个问题后,我有一个小文本在括号之间有文字,我想提取那个文本,所以我写了这个表达式:

/(\([^\)]+\))/i

但这只会在第一个(和最后一个)之间提取文字而忽略文本的其余部分 有没有办法提取全文,如:

i want(to) extract this text

来自:

this is the text that (i want(to) extract this text) from

可能有多个括号括起来的子文本。

由于

修改 发现这个:

preg_match_all("/\((([^()]*|(?R))*)\)/", $rejoin, $matches);

从接受的答案中提供的链接非常有用

4 个答案:

答案 0 :(得分:6)

是的,你可以使用这种模式

   v                   v
 (\([^\)\(]*)+([^\)\(]*\))+
 ------------ -------------
      |            |
      |            |->match all (right)brackets to the right..
      |
      |->match all (left)brackets to the left

Demo


如果你有像这样的递归模式

,上面的模式将不起作用
(i want(to) (extract and also (this)) this text)
                              ------
            -------------------------

在这种情况下,您可以使用elclanrs建议的recursive pattern


您也可以通过维持()的数量

所以, 假设noOfLB(的计数而noOfRB)的计数

  • 继续迭代字符串中的每个字符并保持第一个 (
  • 的位置
  • 如果找到,则增加noOfLB(
  • 如果找到则增加noOfRB)
  • 如果noOfLB == noOfRB,您已找到最后 )的最后位置

我不知道php所以我会在c#

中实现上述算法
public static string getFirstRecursivePattern(string input)
{
    int firstB=input.IndexOf("("),noOfLB=0,noOfRB=0;
    for(int i=firstB;i<input.Length && i>=0;i++)
    {
         if(input[i]=='(')noOfLB++;
         if(input[i]==')')noOfRB++;
         if(noOfLB==noOfRB)return input.Substring(firstB,i-firstB+1);
    }
    return "";
}

答案 1 :(得分:2)

您将需要递归子模式来解决此问题。这是适用于您的正则表达式:

$str = 'this is the text that (i want(to) extract this text) from';
if (preg_match('/\s* \( ( (?: [^()]* | (?0) )+ ) \) /x', $str, $arr))
   var_dump($arr);

<强>输出:

string(28) "i want(to) extract this text"

答案 2 :(得分:0)

您还可以使用子字符串:

$yourString = "this is the text that (i want(to) extract this text) from";

$stringAfterFirstParen = substr( strstr( $yourString, "(" ), 1 );

$indexOfLastParen = strrpos( $stringAfterFirstParen, ")" );

$stringBetweenParens = substr( $stringAfterFirstParen, 0, $indexOfLastParen );

答案 3 :(得分:0)

我想我理解这个问题,那就是你想提取“我想要(提取)这个文本”或类似的东西,可能会出现这样的东西:这是(我想要的)文本从

中提取此文本)

如果是这样,您可能会发现以下正则表达式成功(使用$ text定义要检查的变量,$ txt作为匹配情况下创建的变量,然后存储在数组$ t []中):

if (preg_match('/\(\w+.+\)/', $text, $t)) {
$txt = $t[0];
} else {
$txt = "";
}
echo $desired=substr($txt,1,-1);

RegEx的根源是:(\ w +。+),这里是代码的解释:

  1. 匹配字符“(”字面上的«(»
  2. 匹配单个字符“字符”(字母,数字和下划线)«\ w +»在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)«+»
  3. 匹配任何不是换行符的单个字符«。+»在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)«+»
  4. 匹配字符“)”字面意思«)»
  5. 将括号内的文本放入新的变量$ desired中。通过选择一端减少一个字符的子字符串来显示$ desired字符,从而消除边界括号。«echo $ desired = substr($ txt,1-1)»
  6. 使用上面我能够显示:我希望(从)变量$ text中提取此文本=这是(我想要(提取)此文本)的文本。如果希望从(to)中拉出“to”,我建议你通过正则表达式循环运行变量,直到在表达式中找不到更多的(),它返回一个空值并将返回的值连接到形成感兴趣的变量。

    祝你好运, 史蒂夫