在进行正则表达式替换时跟踪位置

时间:2014-01-17 22:46:54

标签: c# regex

考虑以下字符串"a b c d efg hi j"。如果我正在跟踪位置7 "d",我在删除所有空格后如何跟踪它 - 例如,对于"abcdefghij",更新后的位置应为4。

1 个答案:

答案 0 :(得分:1)

如果要跟踪字符串中的某个字符位置,并且在字符串替换发生后使用简单字符搜索无法再次找到该字符,则可以重新计算每个字符的跟踪位置单字符串替换。

重新计算跟踪字符串位置需要考虑三种情况:

  1. 要替换的文字位于跟踪位置之前的,并且跟踪的字符不是要替换的文本的一部分:重新计算跟踪的位置,如

    trackedPos + = newSubstituteStringPortion.Length - ReplacedStringPortion.Length

  2. 要替换的文字位于跟踪位置后面的 :无需重新计算,因为跟踪位置不会改变。

  3. 要替换的文本部分内的跟踪位置 :在这种情况下,您需要就您的代码在这种情况下应该执行的操作达成一致。可能的约定可能是:

    • 跟踪位置保持不变。
    • 跟踪位置不再有效。
    • 尝试在替代字符串中查找跟踪的字符。如果字符在替换字符串中多次出现,您仍然需要定义一个关于代码应该做什么的约定。
  4. 如果Regex.Replace是选择的方法,则可以使用其中一个接受MatchEvaluator委托的重载来重新计算跟踪位置。

    这样的MatchEvaluator委托可能如下所示:

    public string TrackPositionMatchEvaluator(Match match)
    {
        if (match.Index + match.Length <= trackedPosition)
        {
            // Case #1 (see explanation above)
            trackedPos += substituteString.Length - match.Length;
        }
        else if (match.Index <= trackedPosition)
        {
            // Case #3 (see explanation above)
            ... here put the implementation for your convention(s) of case #3
        }
    
        // Case #2 (see explanation above) doesn't do any recalculation...
    
        return substituteString;
    }
    

    如果您当前的代码使用其他一些不使用此类委托的“ReplaceAll”函数,您可能需要将其更改为以顺序方式执行单个替换的循环,以便您可以应用上面给出的规则。根据你如何获得要替换的字符串部分的偏移量,这个循环应该可以“向后”进行替换,即从字符串的后面到其前面。