正则表达式替换字符串中的所有点,除非在圆括号之间

时间:2012-02-09 14:51:51

标签: regex

我正在尝试找到正确的正则表达式来执行以下操作:

输入:'$ MM.Player.Panning(1,0.1)'; 输出'$ MM-> Player->平移(1,0.1)';

我无法弄清楚如何用' - >'替换点,而不用圆括号之间的点替换。

任何意见或建议都将受到高度赞赏

3 个答案:

答案 0 :(得分:1)

一个建议是:(因为您可能会在括号中传递数字,而外部的点被非数字包围)

尝试(\D)\.(\D)并替换为$1->$2

答案 1 :(得分:1)

使用正则表达式的最佳解决方案是

尝试一个小函数来解析你的字符串:

(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.
}

它很完美,我试过了。您的输入和输出是正确的。

答案 2 :(得分:0)

彼得,你说:

  

如果你有一个更简单,更小的解决方案,我仍然想知道

更多更简单,更小可以吗? :)

以下是整个解决方案:

$regex = '~\([^)]*\)(*SKIP)(*F)|(\.)~';
$subject = '$MM.Player.Panning(1, 0.1)';
$replaced = preg_replace($regex,"->",$subject);

你的情况直接来自Match (or replace) a pattern except in situations s1, s2, s3 etc。我们使用这个简单的正则表达式:

\([^)]*\)(*SKIP)(*F)|\.

交替的左侧匹配完成(parenthesized expressions)然后故意失败并跳过该部分字符串。右侧与点匹配,我们知道它们是正确的点,因为它们与左侧的表达不匹配。

这些是我们需要替换的点。您可以在online demo

的底部看到结果

参考

How to match (or replace) a pattern except in situations s1, s2, s3...