2

正規表現が正しく機能しないのはなぜですか?

string findarg2 = ",\\s(.*?),\\s";

foreach (Match getarg2 in Regex.Matches(tmptwopart, findarg2))
if (getarg2.Success)
{
    for (int m = 1; m < getarg2.Groups.Count; m++)
    {
        int n;
        bool needpointer = false;
        for (n = getarg2.Groups[m].Value.Length - 1; n > -1; n--)
        {
            if (getarg2.Groups[m].Value[n] == ' ')
                break;
            else if (getarg2.Groups[m].Value[n] == '*')
            {
                needpointer = true;
                break;
            }
        }
        n++;

        string part1 = getarg2.Groups[m].Value.Remove(n);
        string part2 = getarg2.Groups[m].Value.Remove(0, n);
        Console.WriteLine(getarg2.Groups[m] + " =->" +part1+ " AND " + part2);
        Console.ReadKey();
        if (needpointer)
        {
            createarglist.Append("<< *(" + part1 + ")" + part2);
        }
        else
        {
            createarglist.Append("<< " + part2);
        }
        createarglistclear.Append(part2+",");
    } }

例 入力文字列:

(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2)

出力:

<< check<< *(float *)y1

期待される:

<< check<< *(float *)x1<< *(float *)y1<< *(float *)x2
4

3 に答える 3

4

これは、実行中に末尾のコンマを消費しているためです。つまり、末尾のコンマは既に一致しているため、一致させようとしている次のエンティティの先頭のコンマとしては一致しません。代わりに幅ゼロのアサーションを使用してください。

string findarg2 = "(?<=,\\s)(.*?)(?=,\\s)";

これらは、それぞれ「後読み」アサーションおよび「先読み」アサーションとして知られています。

于 2013-11-14T15:47:49.317 に答える
3

式が機能しない理由は、コンマを「消費」するためです。一致する部分は、checkその後のコンマも消費し、一致を防ぎfloat *x1ます。に一致する式も同様float *y1です。

先読みと後読みを使用するように式を変更すると、うまくいくはずです。ただし、最初の一致の前にコンマがなく、最後の一致の後にコンマがないため、それだけでは不十分な場合があります。

この場合に使用するより適切な表現は次のとおりです。

(?<=[(,])\\s*([^,)]*)\\s*(?=[,)])

完全なコード例を次に示します。

foreach (Match m in Regex.Matches(
    "(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2)"
,   "(?<=[(,])\\s*([^,)]*)\\s*(?=[,)])")
) {
    for (var i = 1 ; i != m.Groups.Count ; i++) {
        Console.WriteLine("'{0}'", m.Groups[i]);
    }
}

これは、期待どおりに 6 つのグループを生成するideone のデモです。

'DWORD code'
'bool check'
'float *x1'
'float *y1'
'float *x2'
'float *y2'
于 2013-11-14T15:48:29.110 に答える
0

これはワンショットで実行できます。

string input = "(DWORD code, bool check, float *x1, float *y1, float *x2, float *y2)";
string pattern = @"(?:\([^,]*,\s*[^\s,]*\s+([^,]+)|\G),\s+(\S+)\s*( \*)?((?>[^*,)]+))(?>(?=,[^,]+,)|.*)";
string replacement = "$1<< *($2$3)$4";
Regex rgx = new Regex(pattern);
string result = "<<" + rgx.Replace(input, replacement);
于 2013-11-14T16:04:27.187 に答える