最後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