问题描述
我有一个字符串,我想从中将文本保留在一对方括号内,并删除括号之外的所有内容:
你好[123] {45}世界(67)
你好,那里(8)[9] {0}
所需的输出:
[123] {45}(67)(8)[9] {0}
代码已尝试但失败了:
$re = '/[^()]*+(\((?:[^()]++|(?1))*\))[^()]*+/';
$text = preg_replace($re,'$1',$text);
解决方法
如果字符串中的值始终是一个右括号与一个右括号配对且没有嵌套部分,则可以匹配所有要保留的括号对,并匹配除想要保留的括号之外的所有其他字符删除。
(?:\[[^][]*]|\([^()]*\)|{[^{}]*})(*SKIP)(*F)|[^][(){}]+
说明
-
(?:
非捕获胶-
\[[^][]*]
与[...]
匹配 -
|
或 -
\([^()]*\)
与(...)
匹配 -
|
或 -
{[^{}]*}
与{...}
匹配
-
-
)
关闭非捕获组 -
(*SKIP)(*F)|
consume characters that you want to avoid,and that must not be a part of the match result -
[^][(){}]+
匹配1倍以上列出的1个字符以外的其他字符
示例代码
$re = '/(?:\[[^][]*]|\([^()]*\)|{[^{}]*})(*SKIP)(*F)|[^][(){}]+/m';
$str = 'Hello [123] {45} world (67)
Hello There (8) [9] {0}';
$result = preg_replace($re,'',$str);
echo $result;
输出
[123]{45}(67)(8)[9]{0}
如果要删除所有其他值:
(?:\[[^][]*]|\([^()]*\)|{[^{}]*})(*SKIP)(*F)|.
,
看起来您也想定位嵌套的内容。已经有questions关于如何匹配平衡括号的信息。调整其中一种模式以适合您的需求,例如像
$pattern = '/\((?:[^)(]*(?R)?)*+\)|\{(?:[^}{]*+(?R)?)*\}|\[(?:[^][]*+(?R)?)*\]/';
您可以try this on Regex101。提取那些with preg_match_all
and implode
the matches。
if(preg_match_all($pattern,$str,$out) > 0)
echo implode(' ',$out[0]);
如果您需要匹配外部内容,即使采用这种模式,您也可以使用也使用@Thefourthbird (*SKIP)(*F)
的in his elaborately answer!用于跳过方括号see this other demo。
如果方括号未嵌套,则满足以下条件:
<tbody>
<tr>
<th>Return ID</th>
<th>ZD Ticket</th>
<th>Return Status</th>
<th>Customer Email</th>
</tr>
<tr>
<?php
foreach($returnsTable as $item){
echo "<td>".$item."</td>";
}
?>
</tr>
</tbody>
</table>
</div>
Demo 。
故障:
[^[{(\]})]+(?=[[{(]|$)