我在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;
}
}
通过我使用逐字字符串和转义字符串进行测试的方式。它不会编译否则
答案 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+");