0

给定文本,例如:

This is my [position].
Here are some items:
[items]
    [item]
         Position within the item: [position]
    [/item]
[/items]

Once again, my [position].

我需要匹配 first 和 last [position],但不是[position] inside [items]...[/items]。这对正则表达式可行吗?到目前为止,我所拥有的是:

Regex.Replace(input, @"\[position\]", "replacement value")

但这取代了我想要的更多。

4

3 回答 3

2

正如 Wug 所提到的,正则表达式不擅长计数。一个更简单的选择是只找到您正在寻找的所有令牌的位置,然后遍历它们并相应地构造您的输出。也许是这样的:

public string Replace(input, replacement)
{
    // find all the tags
    var regex = new Regex("(\[(?:position|/?item)\])");
    var matches = regex.Matches(input);

    // loop through the tags and build up the output string
    var builder = new StringBuilder();
    int lastIndex = 0;
    int nestingLevel = 0;
    foreach(var match in matches)
    {
        // append everything since the last tag;
        builder.Append(input.Substring(lastIndex, (match.Index - lastIndex) + 1));

        switch(match.Value)
        {
            case "[item]":
                nestingLevel++;
                builder.Append(match.Value);
                break;
            case "[/item]":
                nestingLevel--;
                builder.Append(match.Value);
                break;
            case "[position]":
                // Append the replacement text if we're outside of any [item]/[/item] pairs
                // Otherwise append the tag
                builder.Append(nestingLevel == 0 ? replacement : match.Value);
                break;
        }
        lastIndex = match.Index + match.Length;
    }

    builder.Append(input.Substring(lastIndex));
    return builder.ToString();
}

(免责声明:尚未测试。甚至尝试编译。为不可避免的错误提前道歉。)

于 2012-08-23T20:27:20.707 回答
0

你可能会逃脱:

Regex.Replace(input,@"(?=\[position\])(!(\[item\].+\[position\].+\[/item\]))","replacement value");

我不知道,我讨厌这样的人。但这是 xml 解析的工作,而不是正则表达式。如果你的括号真的是括号,只需搜索并用胡萝卜替换它们,然后 xml 解析。

于 2012-08-23T18:18:37.733 回答
0

如果你检查它两次怎么办。像,

s1 = Regex.Replace(input, @"(\[items\])(\w|\W)*(\[\/items\])", "")

这将为您提供:

This is my [position].
Here are some items:
Once again, my [position].

如您所见,项目部分已被提取。然后在 s1 你可以提取你想要的位置。像,

s2 = Regex.Replace(s1, @"\[position\]", "raplacement_value")

这可能不是最好的解决方案。我非常努力地在正则表达式上解决它,但没有成功。

于 2012-08-23T20:02:37.263 回答