尝试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);
从接受的答案中提供的链接非常有用
答案 0 :(得分:6)
是的,你可以使用这种模式
v v
(\([^\)\(]*)+([^\)\(]*\))+
------------ -------------
| |
| |->match all (right)brackets to the right..
|
|->match all (left)brackets to the left
如果你有像这样的递归模式
,上面的模式将不起作用(i want(to) (extract and also (this)) this text)
------
-------------------------
在这种情况下,您可以使用elclanrs建议的recursive pattern
您也可以通过维持(
和)
的数量
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 +。+),这里是代码的解释:
使用上面我能够显示:我希望(从)变量$ text中提取此文本=这是(我想要(提取)此文本)的文本。如果希望从(to)中拉出“to”,我建议你通过正则表达式循环运行变量,直到在表达式中找不到更多的(),它返回一个空值并将返回的值连接到形成感兴趣的变量。
祝你好运, 史蒂夫