删除 [] {} () 括号外的文本

Remove text outside of [] {} () bracket

我有一个字符串,我想从中保留一对括号内的文本并删除括号外的所有内容:

Hello [123] {45} world (67)
Hello There (8) [9] {0}

期望的输出:
[123] {45} (67) (8) [9] {0}

已尝试但失败的代码:

$re = '/[^()]*+(\((?:[^()]++|(?1))*\))[^()]*+/';
$text = preg_replace($re, '', $text);

如果括号没有嵌套,下面的内容就足够了:

[^[{(\]})]+(?=[[{(]|$)

Demo.

细分:

[^[{(\]})]+     # Match one or more characters except for opening/closing bracket chars.
(?=[[{(]|$)     # A positive Lookahead to ensure that the match is either followed by
                # an opening bracket char or is at the end of the string.

如果字符串中的值始终是左括号和右括号配对且没有嵌套部分,则可以匹配所有要保留的括号对,并匹配除括号外的所有其他字符想删除。

(?:\[[^][]*]|\([^()]*\)|{[^{}]*})(*SKIP)(*F)|[^][(){}]+

说明

  • (?: 非捕获组
    • \[[^][]*] 匹配来自 [...]
    • |
    • \([^()]*\) 匹配来自 (...)
    • |
    • {[^{}]*} 匹配来自 {...}
  • )关闭非捕获组
  • (*SKIP)(*F)| consume characters that you want to avoid, and that must not be a part of the match result
  • [^][(){}]+ 匹配除列出的 1 个以外的任何字符 1 次以上

Regex demo | Php demo

示例代码

$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)|.

Regex demo

看起来你也想定位嵌套的东西。已经有 questions 关于如何匹配平衡括号。调整其中一种模式以满足您的需求,例如像

$pattern = '/\((?:[^)(]*(?R)?)*+\)|\{(?:[^}{]*+(?R)?)*\}|\[(?:[^][]*+(?R)?)*\]/';

你可以try this on Regex101. Extract those with preg_match_all and implode the matches.

if(preg_match_all($pattern, $str, $out) > 0)
  echo implode(' ', $out[0]);

如果你需要匹配外面的东西,即使使用这种模式你也可以使用(*SKIP)(*F) that also used @Thefourthbird ! For skipping the bracketed see this other demo