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

Posted

技术标签:

【中文标题】删除 [] () 括号外的文本【英文标题】:Remove text outside of [] () bracket删除 [] () 括号外的文本 【发布时间】:2021-02-20 17:03:57 【问题描述】:

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

你好 [123] 45 世界 (67) 你好 (8) [9] 0

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

代码尝试但失败:

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

【问题讨论】:

【参考方案1】:

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

(?:\[[^][]*]|\([^()]*\)|[^]*)(*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

【讨论】:

我会将其标记为答案,只需要更多帮助 如果 $str 在我想要保留的括号之外还有一些其他字符(如 @#)怎么办。 @www.friend0.in 您可以将这些字符添加到最后的字符类中以排除匹配它们(?:\[[^][]*]|\([^()]*\)|[^]*)(*SKIP)(*F)|[^][()@#]+ 见regex101.com/r/kGLXjU/1 嗨。只是一个后续问题:我需要做同样的事情,但不同的是我需要括号本身也消失,所以在你的例子中我需要它只返回“1234567890”。我需要改变什么?【参考方案2】:

看起来你也想定位嵌套的东西。关于如何匹配平衡括号已经有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]);

如果你需要匹配外面的东西,即使使用这种模式,你也可以使用(*SKIP)(*F) 也使用@Thefourthbird in his elaborately answer!用于跳过括号内的see this other demo。

【讨论】:

好久没见到你了,但我记得你过去创造了一些很酷的图案。这个也很好:-) +1 很高兴再次见到你@Thefourthbird :) 谢谢你! 很棒的代码,它还保留了空间,从而提高了可读性。只需要一个帮助;如果 $str 在我想保留的括号之外还有一些其他字符,如 @# 怎么办。 @www.friend0.in 好吧,我只是用了一个空间来内爆 - 实际上外面什么都没有,你写了 remove all outside the bracket : )。如果您想保留原始空格或添加字符,只需将另一个替换附加到模式,例如:|[@# ] 并在空白处内爆。 @www.friend0.in 仅供参考,您也可以将此模式与(*SKIP)(*F) 一起使用,并匹配括号外的内容(类似于第四只鸟)see this demo - 不同之处在于它适用于嵌套的东西。【参考方案3】:

如果括号没有嵌套,以下就足够了:

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

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.

【讨论】:

它也适合(这个)。我认为需要反向引用。

以上是关于删除 [] () 括号外的文本的主要内容,如果未能解决你的问题,请参考以下文章

autojs,读取一行删除一行,停止自己外的脚本

autojs,读取一行删除一行,停止自己外的脚本

如何从python中的文本文档中删除所有标点符号和其他符号?

如何对法律领域的文本文档进行分类

在oracle中提取括号外的数据

如何用括号外的逗号分割字符串?