C#中的正则表达式和非记录组

时间:2011-08-19 09:31:21

标签: c# regex f#

我在C#中遇到regexp问题。 我一直在F#中使用这些模式并且它工作正常,所以我不明白为什么它在C#中不起作用。

所以让我说我有一个muline输入文件。我需要解析此文件以获取特定数据:

例:

    Lorem ipsum dolor sit amet, consectetur adipiscing elit (Token1 : 42)
    Aliquam id ante ut ante tempus fringilla Token2 (ante ut ) : 45
    Morbi varius adipiscing lacus, eget pellentesque tellus vulputate Token3 :  43

我基本上需要在单个匹配中检索在Token1,Token2,Token3之后写入的数字(即仅仅想要我的数字)。 我在F#中使用的模式如下:

PatternToken1 = "(?:Token1 : )(\d+)"
PatternToken2 = "(?:Token2.* : )(\d+)"
PatternToken3 = "(?:Token3 : )(\d+)"

所以我的问题是以下问题: 在F#中匹配我输入字符串的模式会给我以下结果:

 MatchedToken1 = 42
 MatchedToken2 = 45
 MatchedToken3 = 43

在C#中我会得到以下结果:

 MatchedToken1 = Token1 : 42
 MatchedToken2 = Token2 (ante ut ) : 45
 MatchedToken3 = Token3 :  43

为什么这在F#中起作用而在C#中起作用?我必须使用什么样的模式才能在C#中工作?

编辑: 这是我用来匹配c#中的模式的代码:

 abstract class  PatternMatcherBaseEntity<T>
{
    protected Regex Pattern;
    protected T Match;


    private static TK Convert<TK>(string input)
    {
        TK res=default(TK);
        var converter = TypeDescriptor.GetConverter(typeof(TK));
        if(converter != null)
        {
            try
            {
                res = (TK) converter.ConvertFromString(input);
            }
            catch (Exception)
            {
                res = default(TK);
            }

        }
        return res;
    }


    protected bool Matcher(string s)
    {
        var res = false;
        //var matchedData = Regex.Match(s, Patterm);
        var content = Pattern.Matches(s);
        if(content.Count>0)
        {
            //Match = Convert<T>(content.Value);
            Match = Convert<T>(content[0].Value);
            res = true;
        }
        return res;
    }

    public T MatchGetter(String stringToMatch)
    {
        T ret = default(T);
        if(stringToMatch != String.Empty)
        {
            ret = stringToMatch.Match()
            .With(Matcher, x => Match)
            .Else(x => default(T))
            .Do();
        }
        return ret;
    }
}

通过我使用逐字字符串和转义字符串进行测试的方式。它不会编译否则

4 个答案:

答案 0 :(得分:1)

尝试使用以下内容:

PatternToken1 = "(?<=Token1 : )(\d+)"
PatternToken2 = "(?<=Token2.* : )(\d+)"
PatternToken3 = "(?<=Token3 : )(\d+)"

答案 1 :(得分:1)

(?:Token1 : )(\d+)
             ^   ^

使用此括号,您将创建一个捕获组,将匹配放在捕获组的括号内。

你现在就像这样使用它

var content = Pattern.Matches(s);

现在Matches返回一个

的数组

content[0]包含完整匹配的字符串

content[1]包含第1组的匹配部分

在这里

Match = Convert<T>(content[0].Value);

您使用的是MatchCollection数组content

的错误部分

您的结果在第1组中,因此您需要获得第1组

Match = Convert<T>(content[1].Value);

答案 2 :(得分:0)

我不知道F#但是在C#中你需要通过将它们加倍来反转斜杠,或者使用@字符串前缀:

PatternToken1 = "(?:Token1 : )(\\d+)";
PatternToken2 = @"(?:Token2.* : )(\d+)";
PatternToken3 = @"(?:Token3 : )(\d+)";

答案 3 :(得分:0)

在C#中你需要(?:)匹配但不包含在匹配结果中:

Regex.Match(str, @"(?:Token1) : (\d+)"); // result =  42
Regex.Match(str, @"(?:Token2).* : )(\d+)"); // result = 45
Regex.Match(str, @"(?:Token3).+:.+\d+"); // result = 43
编辑 - 意外地在那里有一个流浪的paran - 感谢评论员指出 - 也完全误解了问题的重点......认为OP想要得到匹配的单词 - 有趣的部分是我甚至打开“匹配但不包括”的问题。不确定我在想什么 - 无论如何,新代码和这次复制/粘贴以避免额外的paran ...

    string str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit (Token1 : 42)      Aliquam id ante ut ante tempus fringilla Token2 (ante ut ) : 45      Morbi varius adipiscing lacus, eget pellentesque tellus vulputate Token3 :  43  ";
    Match m1 = Regex.Match(str, @"(?<=Token1 : +)\d+");
    Match m2 = Regex.Match(str, @"(?<=Token2.* : +)\d+");
    Match m3 = Regex.Match(str, @"(?<=Token3 : +)\d+");
    MatchCollection mAll = Regex.Matches(str, @"(?<=Token\d[^\:]+: +)\d+");