在尝试了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);
从已接受的答案中提供的链接来看非常有用
是的,您可以使用此模式
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)
------
-------------------------
在这种情况下,您可以使用elclans推荐的递归模式
您也可以通过维护(
和)
的计数,在不使用的情况下使用regex
所以,假设noOfLB
是(
的计数,noOfRB
是)
的计数
- 继续迭代字符串中的每个字符,并保持第一个
(
的位置 - 如果你发现(
- 如果找到,则递增noOfRB)
- 如果noOfLB==noOfRB,则您已找到last
)
的最后一个位置
我不知道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 "";
}
您将需要递归子模式来解决此问题。以下是适用于您的正则表达式:
$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"
您也可以使用子字符串:
$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 );
我想我理解这个问题,那就是你想从可能看起来像这样的东西中提取"我想提取这个文本"或类似的东西:这是从中提取的文本
如果是这样的话,您可能会发现以下正则表达式的成功(使用$text定义要检查的变量,并使用$txt作为在匹配的情况下创建的变量,然后将其存储在数组$t[]中):
if (preg_match('/'('w+.+')/', $text, $t)) {
$txt = $t[0];
} else {
$txt = "";
}
echo $desired=substr($txt,1,-1);
RegEx在它的根是:(''w+.+),这里是代码的解释:
- 匹配字符"("字面意思为«(»
- 匹配一个"单词字符"(字母、数字和下划线)«''w+»在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)«+»
- 匹配任何不是换行符«的单个字符+»在一次和无限次之间,尽可能多次,根据需要回馈(贪婪)«+»
- 匹配字符")"字面意思为«)»
- 将括号内的文本放入一个新变量$required中。通过选择两端减少一个字符的子字符串来显示$个所需字符,从而消除边界括号。«echo$desired=substr($txt,1-1)»
使用上面的内容,我可以显示:我想从变量$text中提取此文本=这是我想从中提取的文本。如果希望从(to)中提取"to",我建议您通过regex循环运行该变量,直到在表达式中找不到更多的(),并且它返回一个null值,并将返回的值连接起来以形成感兴趣的变量。
祝你好运,Steve