示例可能效果最好。
-
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}"));