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

时间:2015-08-25 16:46:50

标签: php arrays string escaping

示例可能效果最好。

  • 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;
            }
        }

1 个答案:

答案 0 :(得分:1)

编写一个简单的解析器:

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

嵌套解析器

为了便于理解,我现在要忘记\规则。

假设你有: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}"));