php - 用用户输入的 2 个或更多子字符串替换用户字符串的确切部分 - 怎么做?
php - Replace exact part of user's string with 2 or more substrings also from user input - how to do?
我正在构建一个网络应用程序,用户键入特殊类型的代码(见下文),我的这个脚本 "decodes" 并创建代码的各个变体,然后将每个代码发送到 SQL查询。现在,我被困在代码需要转换的部分:
A1 B2 - C3 + D4 / E5 / E6 C3 / A5
这些(将斜杠“/”解释为 OR):
A1 B2 - C3 + D4 C3
A1 B2 - C3 + E5 C3
A1 B2 - C3 + E6 C3
A1 B2 - C3 + D4 A5
A1 B2 - C3 + E5 A5
A1 B2 - C3 + E6 A5
这是我目前得到的:
<?php
// User input
$input = "A1 B2 - C3 + D4 / E5 / E6 C3 / A5";
print_r($input);
// Check how many times user input have "/" (returns INT in $occurencesOfOR and makes complex array $matches of matched substrings)
$occurencesOfOR = preg_match_all("/(?: \/ )?(?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]? \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?(?: \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?)*/", $input, $matches);
print_r($occurencesOfOR);
// Replacing places of matched pattern with X
$dummyCode = "X";
$inputStripped = preg_replace("/(?: \/ )?(?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]? \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?(?: \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?)*/", $dummyCode, $input);
print_r($inputStripped);
print_r($matches);
// Creating simple array with individual OR codes
$orCodesArray = [];
foreach ($matches[0] as $match) {
array_push($orCodesArray, $match);
}
print_r($orCodesArray);
// Creating multidimensional array from individual codes created by preg_split()
$individualCodesSubarrays = [];
foreach ($orCodesArray as $code) {
$codeSet = preg_split("/ \/ /", $code);
array_push($individualCodesSubarrays, $codeSet);
}
print_r($individualCodesSubarrays);
// Count how many subarrays has $individualCodesArray (returns INT)
$counterOfArrays = count($individualCodesSubarrays);
echo $counterOfArrays;
// Getting position of X-es in stripped user input
$lastPos = 0;
$positions = [];
$position = "";
while (($lastPos = strpos($inputStripped, $dummyCode, $lastPos)) !== false) {
$positions[] = $lastPos;
$lastPos = $lastPos + strlen($dummyCode);
}
foreach ($positions as $position) {
echo $position."\n";
}
但是从那里我不知道如何进一步追求。我找不到解决方案,如何制作一个函数,将第一个 X
替换为 D4 / E5 / E6
中的每一个,将第二个 X
替换为每个 C3 / A5
以进行上述所有可能的组合.感谢任何帮助。
更新
我已经成功地做到了这一点,但仍然有问题要让它发挥作用。
// Addition to the upper code at the end
$inputStripped2 = [];
for ($c=0; $c < $counterOfArrays; $c++) {
$individualCodesSubrray = $individualCodesSubarrays[$c];
print_r($individualCodesSubrray);
$countCodes = count($individualCodesSubrray);
echo $countCodes."\n";
for ($x=0; $x < $countCodes; $x++) {
$dummyCodeX = "X".$c;
array_push($inputStripped2, str_replace($dummyCodeX, $individualCodesSubrray[$x], $inputStripped));
}
print_r($inputStripped2);
}
实现所需效果的一种方法是首先将字符串拆分为 space(单独)、'+' 或 '-',例如
$input = "A1 B2 - C3 + D4 / E5 / E6 C3 / A5";
$parts = preg_split('/(?<=[A-Za-z0-9])\s+(?=[A-IK-Za-ik-z])|\s+([+-])\s+/', $input, -1, PREG_SPLIT_DELIM_CAPTURE);
这给出:
Array (
[0] => A1
[1] => B2
[2] => -
[3] => C3
[4] => +
[5] => D4 / E5 / E6
[6] => C3 / A5
)
然后可以使用以下方法在 /
上进一步拆分这些值:
foreach ($parts as &$part) {
$part = preg_split('#\s+/\s+#', $part);
}
这给出了以下数组数组:
Array (
[0] => Array (
[0] => A1
)
[1] => Array (
[0] => B2
)
[2] => Array (
[0] => -
)
[3] => Array (
[0] => C3
)
[4] => Array (
[0] => +
)
[5] => Array (
[0] => D4
[1] => E5
[2] => E6
)
[6] => Array (
[0] => C3
[1] => A5
)
)
您现在可以使用 array_reduce
和这样的函数对这些数组进行叉积:
function cross_product($array, $value) {
$output = array();
foreach ($array as $arr) {
foreach ($value as $val) {
$output[] = array_merge($arr, array($val));
}
}
return $output;
}
$init = array_map(function ($v) { return array($v); }, array_shift($parts));
$outputs = array_reduce($parts, 'cross_product', array($init));
最后,您可以输出每个 $outputs
数组的内爆版本,以获得您想要的结果:
foreach ($outputs as $output) {
echo implode(' ', $output) . "\n";
}
输出:
A1 B2 - C3 + D4 C3
A1 B2 - C3 + D4 A5
A1 B2 - C3 + E5 C3
A1 B2 - C3 + E5 A5
A1 B2 - C3 + E6 C3
A1 B2 - C3 + E6 A5
或者,对于输入 "A1 / B2 - C3 + D4 / E5 / E6 C3 + A5"
,您将得到:
A1 - C3 + D4 C3 + A5
A1 - C3 + E5 C3 + A5
A1 - C3 + E6 C3 + A5
B2 - C3 + D4 C3 + A5
B2 - C3 + E5 C3 + A5
B2 - C3 + E6 C3 + A5
我正在构建一个网络应用程序,用户键入特殊类型的代码(见下文),我的这个脚本 "decodes" 并创建代码的各个变体,然后将每个代码发送到 SQL查询。现在,我被困在代码需要转换的部分:
A1 B2 - C3 + D4 / E5 / E6 C3 / A5
这些(将斜杠“/”解释为 OR):
A1 B2 - C3 + D4 C3
A1 B2 - C3 + E5 C3
A1 B2 - C3 + E6 C3
A1 B2 - C3 + D4 A5
A1 B2 - C3 + E5 A5
A1 B2 - C3 + E6 A5
这是我目前得到的:
<?php
// User input
$input = "A1 B2 - C3 + D4 / E5 / E6 C3 / A5";
print_r($input);
// Check how many times user input have "/" (returns INT in $occurencesOfOR and makes complex array $matches of matched substrings)
$occurencesOfOR = preg_match_all("/(?: \/ )?(?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]? \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?(?: \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?)*/", $input, $matches);
print_r($occurencesOfOR);
// Replacing places of matched pattern with X
$dummyCode = "X";
$inputStripped = preg_replace("/(?: \/ )?(?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]? \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?(?: \/ (?:[A-IK-Za-ik-z]|Aa)[1-9][0-9]{0,2}[A-Za-z]?)*/", $dummyCode, $input);
print_r($inputStripped);
print_r($matches);
// Creating simple array with individual OR codes
$orCodesArray = [];
foreach ($matches[0] as $match) {
array_push($orCodesArray, $match);
}
print_r($orCodesArray);
// Creating multidimensional array from individual codes created by preg_split()
$individualCodesSubarrays = [];
foreach ($orCodesArray as $code) {
$codeSet = preg_split("/ \/ /", $code);
array_push($individualCodesSubarrays, $codeSet);
}
print_r($individualCodesSubarrays);
// Count how many subarrays has $individualCodesArray (returns INT)
$counterOfArrays = count($individualCodesSubarrays);
echo $counterOfArrays;
// Getting position of X-es in stripped user input
$lastPos = 0;
$positions = [];
$position = "";
while (($lastPos = strpos($inputStripped, $dummyCode, $lastPos)) !== false) {
$positions[] = $lastPos;
$lastPos = $lastPos + strlen($dummyCode);
}
foreach ($positions as $position) {
echo $position."\n";
}
但是从那里我不知道如何进一步追求。我找不到解决方案,如何制作一个函数,将第一个 X
替换为 D4 / E5 / E6
中的每一个,将第二个 X
替换为每个 C3 / A5
以进行上述所有可能的组合.感谢任何帮助。
更新
我已经成功地做到了这一点,但仍然有问题要让它发挥作用。
// Addition to the upper code at the end
$inputStripped2 = [];
for ($c=0; $c < $counterOfArrays; $c++) {
$individualCodesSubrray = $individualCodesSubarrays[$c];
print_r($individualCodesSubrray);
$countCodes = count($individualCodesSubrray);
echo $countCodes."\n";
for ($x=0; $x < $countCodes; $x++) {
$dummyCodeX = "X".$c;
array_push($inputStripped2, str_replace($dummyCodeX, $individualCodesSubrray[$x], $inputStripped));
}
print_r($inputStripped2);
}
实现所需效果的一种方法是首先将字符串拆分为 space(单独)、'+' 或 '-',例如
$input = "A1 B2 - C3 + D4 / E5 / E6 C3 / A5";
$parts = preg_split('/(?<=[A-Za-z0-9])\s+(?=[A-IK-Za-ik-z])|\s+([+-])\s+/', $input, -1, PREG_SPLIT_DELIM_CAPTURE);
这给出:
Array (
[0] => A1
[1] => B2
[2] => -
[3] => C3
[4] => +
[5] => D4 / E5 / E6
[6] => C3 / A5
)
然后可以使用以下方法在 /
上进一步拆分这些值:
foreach ($parts as &$part) {
$part = preg_split('#\s+/\s+#', $part);
}
这给出了以下数组数组:
Array (
[0] => Array (
[0] => A1
)
[1] => Array (
[0] => B2
)
[2] => Array (
[0] => -
)
[3] => Array (
[0] => C3
)
[4] => Array (
[0] => +
)
[5] => Array (
[0] => D4
[1] => E5
[2] => E6
)
[6] => Array (
[0] => C3
[1] => A5
)
)
您现在可以使用 array_reduce
和这样的函数对这些数组进行叉积:
function cross_product($array, $value) {
$output = array();
foreach ($array as $arr) {
foreach ($value as $val) {
$output[] = array_merge($arr, array($val));
}
}
return $output;
}
$init = array_map(function ($v) { return array($v); }, array_shift($parts));
$outputs = array_reduce($parts, 'cross_product', array($init));
最后,您可以输出每个 $outputs
数组的内爆版本,以获得您想要的结果:
foreach ($outputs as $output) {
echo implode(' ', $output) . "\n";
}
输出:
A1 B2 - C3 + D4 C3
A1 B2 - C3 + D4 A5
A1 B2 - C3 + E5 C3
A1 B2 - C3 + E5 A5
A1 B2 - C3 + E6 C3
A1 B2 - C3 + E6 A5
或者,对于输入 "A1 / B2 - C3 + D4 / E5 / E6 C3 + A5"
,您将得到:
A1 - C3 + D4 C3 + A5
A1 - C3 + E5 C3 + A5
A1 - C3 + E6 C3 + A5
B2 - C3 + D4 C3 + A5
B2 - C3 + E5 C3 + A5
B2 - C3 + E6 C3 + A5