最后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,等等,等等,但是这将是一个肯定火的方式做它,并避免以上所有的混乱。此外,这是一个非常粗糙的思考这样的问题的方式。
你如何从'] 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