2

XMLパーサーを試して使用するいくつかのソリューションを試しました。文字列が常に 100% 有効な XML であるとは限らないため、すべて失敗します。これが私たちの問題です。

次のような文字列があります。

var a = "this is a testxxx of my data yxxx and of these xxx parts yxxx";
var b = "hello testxxx world yxxx ";

"this is a testxxx3yxxx and of these xxx1yxxx";
"hello testxxx1yxxx ";

ここで重要なのは、xxx と yxxx の間のデータに対して何かをしたいということです。上記の例では、単語をカウントし、文字列を単語カウントに置き換える関数が必要です。

文字列 a を処理し、関数を適用して xxx と yxxx の間のデータを変更する方法はありますか? これをコーディングする方法のアイデアを得ようとしているだけなので、今はどの関数でも構いません。

4

6 に答える 6

3

メソッドを使用できますSplit

 var parts = a.Split(new[] {"xxx", "yxxx"}, StringSplitOptions.None)
            .Select((s, index) =>
                {
                    string s1 = index%2 == 1 ? string.Format("{0}{2}{1}", "xxx", "yxxx", s + "1") : s;
                    return s1;
                });

  var result = string.Join("", parts);
于 2012-10-05T08:24:27.137 に答える
3

常に xxx と yxxx になる場合は、提案どおり正規表現を使用できます。

var stringBuilder = new StringBuilder();
Regex regex = new Regex("xxx(.*?)yxxx");
var splitGroups = Regex.Match(a);

foreach(var group in splitGroups)
{
    var value  = splitGroupsCopy[i];

    // do something to value and then append it to string builder

   stringBuilder.Append(string.Format("{0}{1}{2}", "xxx", value, "yxxx")); 

}    

これは基本的なことだと思います。

于 2012-10-05T08:07:05.800 に答える
1

このコードは、「xxx」で区切られた各部分を処理します。「xxx」セパレーターは保持されます。「xxx」セパレーターを保持したくない場合は、「result.Append(separator);」という 2 行を削除します。

与えられた:

"this is a testxxx of my data yxxx and there are many of these xxx parts yxxx"

それは印刷します:

"this is a testxxx>> of my data y<<xxx and there are many of these xxx>> parts y<<xxx"

それがあなたが望むようなものだと思います。「processPart()」に独自の処理を追加します。

using System;
using System.Text;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            string text = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
            string separator = "xxx";
            var result = new StringBuilder();

            int index = 0;

            while (true)
            {
                int start = text.IndexOf(separator, index);

                if (start < 0)
                {
                    result.Append(text.Substring(index));
                    break;
                }

                result.Append(text.Substring(index, start - index));

                int end = text.IndexOf(separator, start + separator.Length);

                if (end < 0)
                {
                    throw new InvalidOperationException("Unbalanced separators.");
                }

                start += separator.Length;

                result.Append(separator);
                result.Append(processPart(text.Substring(start, end-start)));
                result.Append(separator);

                index = end + separator.Length;
            }

            Console.WriteLine(result);
        }

        private static string processPart(string part)
        {
            return ">>" + part + "<<";
        }
    }
}

[編集] 2 つの異なるセパレーターで動作するように修正されたコードは次のとおりです。

using System;
using System.Text;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            string text = "this is a test<pre> of my data y</pre> and there are many of these <pre> parts y</pre>";
            string separator1 = "<pre>";
            string separator2 = "</pre>";
            var result = new StringBuilder();

            int index = 0;

            while (true)
            {
                int start = text.IndexOf(separator1, index);

                if (start < 0)
                {
                    result.Append(text.Substring(index));
                    break;
                }

                result.Append(text.Substring(index, start - index));

                int end = text.IndexOf(separator2, start + separator1.Length);

                if (end < 0)
                {
                    throw new InvalidOperationException("Unbalanced separators.");
                }

                start += separator1.Length;

                result.Append(separator1);
                result.Append(processPart(text.Substring(start, end-start)));
                result.Append(separator2);

                index = end + separator2.Length;
            }

            Console.WriteLine(result);
        }

        private static string processPart(string part)
        {
            return "|" + part + "|";
        }
    }
}
于 2012-10-05T08:19:26.790 に答える
1

私は正規表現グループを使用します:

ここで、文字列内の部分を取得するための私のソリューション:

private static IEnumerable<string> GetParts( string searchFor, string begin, string end ) {
    string exp = string.Format("({0}(?<searchedPart>.+?){1})+", begin, end);
    Regex regex = new Regex(exp);
    MatchCollection matchCollection = regex.Matches(searchFor);
    foreach (Match match in matchCollection) {
        Group @group = match.Groups["searchedPart"];
        yield return @group.ToString();
    }
}

パーツを取得するのと同じように使用できます。

string a = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";

IEnumerable<string> parts = GetParts(a, "xxx", "yxxx");

元の文字列の一部を置き換えるには、正規表現グループを使用して長さと開始位置 (@group.Index、@group.Length) を決定します。

于 2012-10-05T08:30:15.510 に答える
1

このindexOf()関数は、指定された部分文字列が最初に出現したインデックスを返します。

(私のインデックスは少しずれているかもしれませんが)次のようなことをお勧めします:

var searchme = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";

var startindex= searchme.indexOf("xxx");
var endindex = searchme.indexOf("yxxx") + 3; //added 3 to find the index of the last 'x' instead of the index of the 'y' character

var stringpiece = searchme.substring(startindex, endindex - startindex);

そして、あなたはそれを繰り返すことができますstartindex != -1

私が言ったように、インデックスはわずかにずれている可能性があり、どこかに +1 または -1 を追加する必要があるかもしれませんが、これでうまくいくでしょう (と思います)。


これは、単語の代わりに文字を数える小さなサンプル プログラムです。ただし、プロセッサ機能を変更する必要があるだけです。

var a = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
a = ProcessString(a, CountChars);


string CountChars(string a)
{
    return a.Length.ToString();
}

string ProcessString(string a, Func<string, string> processor)
{
    int idx_start, idx_end = -4;
    while ((idx_start = a.IndexOf("xxx", idx_end + 4)) >= 0)
    {
        idx_end = a.IndexOf("yxxx", idx_start + 3);
        if (idx_end < 0)
            break;

        var string_in_between = a.Substring(idx_start + 3, idx_end - idx_start - 3);
        var newString = processor(string_in_between);

        a = a.Substring(0, idx_start + 3) + newString + a.Substring(idx_end, a.Length - idx_end);

        idx_end -= string_in_between.Length - newString.Length;
    }
    return a;
}
于 2012-10-05T08:05:16.013 に答える
1

Regex.Replace を使用すると、次のように、すべての一致が選択したテキストに置き換えられます。

Regex rgx = new Regex("xxx.+yxxx");
string cleaned = rgx.Replace(a, "replacementtext");
于 2012-10-05T08:12:11.933 に答える