我正在尝试找到正确的regexp来执行以下操作:
输入:'$MM.Player.Paning(1,0.1)';输出'$MM->Player->Panning(1,0.1)';
如果不替换圆括号之间的点,我不知道如何用"->"替换这些点。
任何意见或建议都将受到高度赞赏
最好的解决方案是而不是使用regexp。
尝试一个解析字符串的小函数:
(PHP中的函数,我不知道你用的是什么语言)
function dotReplacer($string) {
$parenthesis = 0; // Counts if we are inside parenthesis or not.
$listOfDots = array(); // List of the index of the $string which contain dots to replace.
$listOfElements = array(); // List of elements between these dots. e.g.: $MM, Player and Panning(1, 0.1)
$newString = ''; // The new string to return.
for ($i = 0; $i < strlen($string); $i++) { // Check with every character in the $string...
switch (substr($string, $i, 1)) {
case '(':
$parenthesis++; // If we see an opening parenthesis, increase the level.
break;
case ')':
$parenthesis--; // If we see a closing parenthesis, decrease the level.
break;
case '.':
if ($parenthesis == 0) {
$listOfDots[] = $i; // If we see a dot AND we are not inside parenthesis, include the character index in the list to replace.
}
break;
default:
}
}
$iterator = 0; // Beginning at the start of the string...
foreach ($listOfDots as $dot) {
$listOfElements[] = substr($string, $iterator, $dot - $iterator); // Add the element that is between the iterator and the next dot.
$iterator = $dot + 1; // Move the iterator after the dot.
}
$listOfElements[] = substr($string, $iterator); // Do that one more time for everything that takes place after the last dot.
return implode('->', $listOfElements); // Return an imploded list of elements with '->' between the elements.
}
我试过了,效果很好。您的输入和输出是正确的。
一个建议是:(因为你可能会在括号中传递数字,而括号外的点被非数字包围)
尝试(D).(D)
并替换为$1->$2
Peter,你说:
如果你有一个更简单、更小的解决方案,我仍然想知道
更简单更小行吗?:)
以下是整个解决方案:
$regex = '~([^)]*)(*SKIP)(*F)|(.)~';
$subject = '$MM.Player.Panning(1, 0.1)';
$replaced = preg_replace($regex,"->",$subject);
除了s1、s2、s3等情况外,您的情况完全不符合匹配(或替换)模式。我们使用这个简单的正则表达式:
([^)]*)(*SKIP)(*F)|.
交替的左侧匹配完整的(parenthesized expressions)
,然后故意失败并跳过字符串的该部分。右边匹配点,我们知道它们是右边的点,因为它们与左边的表达式不匹配。
这些是我们需要替换的点。您可以在在线演示的底部看到结果。
参考
如何匹配(或替换)除s1、s2、s3情况外的模式…