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)";

这些分别称为“lookbehind”和“lookahead”断言。

于 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]);
    }
}

这是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 回答