0

次のようなテキストが与えられた場合:

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

Once again, my [position].

最初と最後の を一致させる必要がありますが[position]、内の [位置]を一致させる必要はありません[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

You could maaaaaybe get away with:

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

I dunno, I hate ones like this. But this is a job for xml parsing, not regex. If your brackets are really brackets, just search and replace them with carrots, then xml parse.

于 2012-08-23T18:18:37.733 に答える
0

2回確認したらどうでしょう。お気に入り、

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

これにより、以下が得られます。

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

ご覧のとおり、items セクションが抽出されています。次に、s1 で目的の位置を抽出できます。お気に入り、

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

これは最善の解決策ではない可能性があります。私は正規表現でそれを解決しようとしましたが、成功しませんでした。

于 2012-08-23T20:02:37.263 に答える