为什么我会从preg_replace()函数获得不同的回报?
我对PHP的preg_replace()
函数有问题。为什么我会从preg_replace()函数获得不同的回报?
$string="[y-z]y-z_y[y_z]yav[v_v]"; // i want it to become : [y-z]yellow-zend_yellow[y_z]yav[v_v]
$find = array('/y(?=(?:.(?!\]))*\[)/Um', '/a(?=(?:.(?!\]))*\[)/Um', '/z(?=(?:.(?!\]))*\[)/Um', '/v(?=(?:.(?!\]))*\[)/Um');
$replace = array('yellow', 'avocado', 'zend', 'vodka');
echo preg_replace($find, $replace, $string)."<br><br>"; // display [y-zend]yellow-zend_yellow[y_zend]yellowavodkaocadovodka[v_v]
echo preg_replace('/y(?=(?:.(?!\]))*\[)/Um', 'yellow', $string)."<br><br>"; // display [y-z]yellow-z_yellow[y_z]yellowav[v_v]
echo preg_replace('/z(?=(?:.(?!\]))*\[)/Um', 'zend', $string)."<br><br>"; // display [y-zend]y-zend_y[y_zend]yav[v_v] --Why displaying zend inside[]?
另外,我想知道是否有一种方法有一个附加条件做这个简单的PHP:如果有“] [”之间的“YAV”字符串,我想忽略它。
**[y-z]y-z_y[y_z]yav[v_v] ==> [y-z]yellow-zend_yellow[y_z]yav[v_v]**
OR
$var=[y-z]y-z[y_z]yav[v_v]; ==> $var=[y-z]yellow-zend[y_z]yav[v_v];
最后Z]匹配becase的你告诉它使用正展望未来匹配负面看,它基本上是一个矛盾的说法。
你告诉它匹配z如果lookahead匹配,而不匹配你不想要的,所以它匹配你不想要的,并说它确定匹配。无论如何,这在我的脑海中是有道理的。
https://regex101.com/r/nX5dQ6/1
您可以量化你的规则来匹配多个字符序列,它肯定更容易与yellow-zend_yellow
取代y-z_y
但没有上下文,这是不可能的说,如果这是可能的。
/z(?=(?:.(?!\]))*\[)/Um
z matches the character z literally (case sensitive)
(?=(?:.(?!\]))*\[) Positive Lookahead - Assert that the regex below can be matched
(?:.(?!\]))* Non-capturing group
Quantifier: * Between zero and unlimited times, as few times as possible, expanding as needed [lazy]
. matches any character (except newline)
(?!\]) Negative Lookahead - Assert that it is impossible to match the regex below
\] matches the character ] literally
\[ matches the character [ literally
U modifier: Ungreedy. The match becomes lazy by default. Now a ? following a quantifier makes it greedy
m modifier: multi-line. Causes^and $ to match the begin/end of each line (not only begin/end of string)
个人我可能会做一个标记生成器它的想法是preg_match_all改为使用,这样
$matches = null;
$returnValue = preg_match_all('/(?P<T_OPEN>\[)|(?P<T_CLOSE>\])|(?P<T_Y>y)|(?P<T_X>x)|(?P<T_Z>z)|(?P<T_SEPH>\-)|(?P<T_SEPU>\_)/', '[y-z]y-z_y[y_z]yav[v_v]', $matches, PREG_PATTERN_ORDER);
返回
array (
0 =>
array (
0 => '[',
1 => 'y',
2 => '-',
3 => 'z',
4 => ']',
...
),
'T_OPEN' =>
array (
0 => '[',
1 => '',
2 => '',
3 => '',
4 => '',
..
并与一些后处理这可以简化成一个令牌列表
array('T_OPEN', 'T_Y', 'T_SEPH', 'T_Z', 'T_CLOSE', ...);
哪些是命名的捕获组,那么这是很平凡的,如果你是[],或不含在写一些逻辑来确定,或者如果T_Y,T_X,T_Z是之前由另一T_Y,T_X, T_Z令牌,这是最可靠的方法。
处理它下降到只有令牌上的[0] [0]比赛使用一个for循环,看看别人有这样的值(未测试,但是这是它的基础)
$total = count($matches[0][0]);
// remove numbered keys this is just an array of all the string keys, our tokens
$tokens = array_filter(function($item){
return preg_match('/^[^0-9]/', $item);
}, array_keys($matches));
$tokens[] = 'T_UNKNOWN'; //add a default token for validation
$tokenstream = array();
for($i=0; $i<$total; $i++){
//loop through the matches for the index,
foreach($tokens as $token){
//loop through the tokens and check $matches[$token][$i] for length
if(strlen($matches[$token][$i]) > 0){
break; //break out of the foreach when we find our token which is now in $token - if we don't find it it's the last token T_UNKNOWN
}
}
$tokenstream[] = $token;
}
然后你从头开始使用令牌建立自己的字符串,
$out = '';
$literal = false;
foreach($tokenstream as $offset => $token){
switch($token){
case 'T_OPEN':
$out .= '[';
$literal = true; //start brackets
break;
case 'T_CLOSE':
$out .= ']';
$literal = false; //end brackets
break;
case 'T_SEPH':
$out .= '-';
break;
case 'T_Y':
if($literal){ //if inside brackets literal y
$out .= 'y';
}else{ // else use the word yellow
$out .= 'yellow';
}
break;
case 'T_UNKNOWN':
//validate
throw new Exception("Error unknown token at offset: $offset");
}
}
你还是会需要弄清楚的T_Z后跟一个T_A,等等,等等,但是这将是一个肯定火的方式做它,并避免以上所有的混乱。此外,这是一个非常粗糙的思考这样的问题的方式。
不,先生,如果我有:$ var = [y-z] y-z [y_z] yav [v_v]; ==> $ var = [y-z] yellow-zend [y_z] yav [v_v] ;.以及如何在字符串中输入单词yav – Mouad
我应该怎么知道,这是你的问题,什么是一些样本输入,一个输入不足以解决这个问题。有很多方法可以做到这一点,你可以使用[y-z]组preg_split等。 – ArtisticPhoenix
谢谢,这是非常接近我的旧解决方案与数组,循环和开关,但它需要大量变量的内存。因为这个原因,我认为如果我使用替换函数的简单方法,我减少了一些内存使用量,但似乎不可能。顺便说一下,我需要这样做一些HTML enc0ding我加载大量的HTML源到内存工作。以编码
p
为例:&#%78%37%30;%70>我需要用不同的值替换单词和单词之间的单词。感谢您的意见我非常感谢^^' – Mouad
你如何从'] ya'告诉''y-'在这里,我刚刚改变了你的生活大声笑,点击我> https:// regex101。com/ – ArtisticPhoenix
do string_replace('y-z_y','yellow-zend_yellow','[y-z] y-z_y [y_z] yav [v_v]'); – ArtisticPhoenix
@ArtisiticPhoenix不,不工作如果var是:[yz] yz [y_z] yav [v_v] ==> [yz] yellow-zend [y_z] yav [v_v]我需要一些东西来处理所有情况,使用大量内存并用特定字符串替换每个单词 – Mouad