算法的后置条件到底应该是什么还不太清楚。在我看来,您想要删除匹配的 ( ) 对。这里的假设是不匹配的括号被单独留下(否则您只需删除所有 ( 和 ))。
所以我猜这意味着输入字符串a(bcdefghijkl(mno)p)q 变为abcdefghijklmnopq 但输入字符串a(bcdefghijkl(mno)pq 变为a(bcdefghijklmnopq。同样,输入字符串 (a)) 将变为 a)。
使用pcre 或许可以做到这一点,因为它确实提供了一些非常规的功能,但我对此表示怀疑。输入字符串的语言不规则;它与上下文无关。 @ArtisticPhoenix 的答案是匹配 complete 对匹配的括号。它不匹配所有嵌套对。在我对语言理论的谦虚理解中,这种嵌套匹配本质上是非常规的。
我建议编写一个解析器来去除匹配的括号对。不得不考虑不匹配的作品有点冗长:
<?php
// Parse the punctuator sub-expression (i.e. anything within ( ... ) ).
function parse_punc(array $tokens,&$iter) {
if (!isset($tokens[$iter])) {
return;
}
$inner = parse_punc_seq($tokens,$iter);
if (!isset($tokens[$iter]) || $tokens[$iter] != ')') {
// Leave unmatched open parentheses alone.
$inner = "($inner";
}
$iter += 1;
return $inner;
}
// Parse a sequence (inside punctuators).
function parse_punc_seq(array $tokens,&$iter) {
if (!isset($tokens[$iter])) {
return;
}
$tok = $tokens[$iter];
if ($tok == ')') {
return;
}
$iter += 1;
if ($tok == '(') {
$tok = parse_punc($tokens,$iter);
}
$tok .= parse_punc_seq($tokens,$iter);
return $tok;
}
// Parse a sequence (outside punctuators).
function parse_seq(array $tokens,&$iter) {
if (!isset($tokens[$iter])) {
return;
}
$tok = $tokens[$iter++];
if ($tok == '(') {
$tok = parse_punc($tokens,$iter);
}
$tok .= parse_seq($tokens,$iter);
return $tok;
}
// Wrapper for parser.
function parse(array $tokens) {
$iter = 0;
return strval(parse_seq($tokens,$iter));
}
// Grab input from stdin and run it through the parser.
$str = trim(stream_get_contents(STDIN));
$tokens = preg_split('/([\(\)])/',$str,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
var_dump(parse($tokens));
我知道这比正则表达式单行代码要多得多,但它确实解决了我理解的问题。我很想知道是否有人可以用正则表达式解决这个问题。