PHP转换字符串不使用正则表达式


PHP transform string without using regular expression

示例可能效果最好。

  • a|b|c需要变成array('a', 'b', 'c')
  • a|'||'}需要变为array('a', ''|', ''}')
  • ab'}aaa|ae'|aa需要变成array('ab'}aaa', 'ae'|aa')

要转换的字符串可以有任何类型的字符,但是有3个"特殊"字符可以被解释为一个简单的字符,只有当它用'转义时。|分隔一个选项,但是,如果转义,需要被解释为一个选项或它的一部分(像任何其他字符一样)。此时{ and }总是会被转义。

问题是我需要在不使用正则表达式的情况下完成此操作。

我已经为这个问题纠结了10个小时,我真的希望任何人都能给出一个简单的答案。

* * *编辑

我的计划是搜索一个|,如果找到,检查它是否被转义。如果是,则继续搜索下一个。当我找到|时,我会取出字符串的第一个选项,并继续相同的方式,直到没有|

while ($positionFound != 1) {
            $intPrevPosition = $intPosition;
            $intPosition = strpos($strTemp, '|', $intPosition);
            if ($intPosition === false || (substr_count($strTemp, '|') == 1 && $strTemp{$intPosition + $intPrevPosition - 1} == '''')) {
                $arrOptions[] = $strTemp;
                $positionFound = 1;
            }
            elseif ($strTemp{$intPosition + $intPrevPosition - 1} != '''') {
                $intPosition = $intPrevPosition + $intPosition;
                $arrOptions[] = substr(substr($strTemp, 0, $intPosition + 1), 0, -1);
                $strTemp = substr($strTemp, $intPosition + 1);
                $intPosition = 0;
            }
        }

编写一个简单的解析器:

$input = "ab''}aaa|ae''|aa"; // ab'}aaa|ae'|aa
$token = "";
$last_char = "";
$len = strlen($input);
$tokens = array();
for ($i = 0; $i < $len; $i += 1) {
    $char = $input[$i];
    if ($char === "|" && $last_char !== "''") {
        $tokens[] = $token;
        $token = "";
    }
    $token .= $char;
    $last_char = $char;
}
$tokens[] = $token; // capture last token
var_dump($tokens);
// array('ab'}aaa', 'ae'|aa')

请注意,在此实现中,转义也在:ab''|cd上触发,输出是array("ab''|cd")而不是array("ab''", "cd")


<

嵌套解析器/strong>

为了便于理解,我将暂时忘记'规则。

假设您有:a{b|c}|{d|e},期望的输出是:abd, abe, acd, ace

首先你要做的是把a{b|c}|{d|e}翻译成:

array(
    "a",
    array("b", "c")
    array("d", "e")
)

如果输入是ab{cd|ef}|{gh|ij},我们想:

array(
    "ab",
    array("cd", "ef")
    array("gh", "ij")
)

当然,多层嵌套也应该工作:a{b|{c|d}}|e

array(
    "a",
    array("b", array("c", "d"))
    "e"
)
下面是解析函数。我还没想好怎么把它们重新组合起来

function parse($string, $i = 0) {
    $token = "";
    $tokens = array();
    for (; $i < strlen($string); $i += 1) {
        $char = $string[$i];
        if ($char === "{") {
            if ($token !== "") {
                $tokens[] = $token;
            }
            $token = "";
            $parse = parse($string, $i + 1);
            $tokens[] = $parse["token"];
            $i = $parse["index"];
            continue;
        }
        if ($char === "}") {
            // end of this part
            if ($token !== "") {
                $tokens[] = $token;
            }
            return array(
                "token" => $tokens,
                "index" => $i
            );
        }
        if ($char === "|") {
            if ($token !== "") {
                $tokens[] = $token;
            }
            $token = "";
            continue;
        }
        $token .= $char;
    }
    return $tokens;
}
var_dump(parse("ab{cd|ef}|{gh|ij}"));