正则表达式匹配整数
本文关键字:整数 正则表达式 | 更新日期: 2023-09-27 18:05:17
我输入的字符串是:
"Monday 11:30am,11 v 2,3 v 4"
我需要替换:
-
11
与Hurricanes
-
2
与Team abc
-
3
withVipers
-
4
withDodgers
-
1
withFrozen Rope
等....
但是我不想在11
中替换1
两次。
我显然不懂正则表达式。但是我尝试了这样做:
string text = File.ReadAllText(CSVpath);
text = Regex.Replace(text,
string.Format(@"[{0} v]", CurrentCode),
string.Format(@"{0} v", TeamName));
text = Regex.Replace(text,
string.Format(@"[v {0}]", CurrentCode),
string.Format(@"v {0}", TeamName));
根据上面的输入字符串,输出将是:
"Monday 11:30am,Hurricanes v Team abc,Vipers v Dodgers"
试试这个regex:
var subject = "Monday 11:30am,11 v 2,3 v 4,5 v 6";
var replaced = Regex.Replace(subject,@"('d+)'s*v's*('d+)","Team$1 with Team$2");
模式分割:
-
('d+)
捕获数字序列并保存在group1 -
's*v's*
检查v
字符包装器两边的零或多个空格。 -
('d+)
捕获数字序列并保存在group2
$1
将第一组替换为Team和第一组的匹配。因此,将11替换为Team11,然后将字面量with
和Team
相加,并将$2
附加在group2的匹配项上。
下面是Regex101的演示
这应该能奏效:'d{1,2}
(注意末尾的空字符!)
从http://msdn.microsoft.com/en-us/library/20bw873z(v=vs.110).aspx,它似乎主要与其他语言中的regex语法一致,您可以使用"'d+"来匹配一个或多个十进制数字。
我没有为你构建整个正确的正则表达式,因为你的问题只是关于匹配给定的单一模式(11而不是1)。
这是我的版本:
/(('d+)('b)(?![:]))/g
将作为:
string text = "Monday 11:30am,11 v 2,3 v 4,5 v 6";
var result = Regex.Replace(text, @"(('d+)('b)(?![:]))", "Team$1");
<<p> 在线演示/strong> 'd+
将捕获尽可能多的数字。 ('b)(?![:])
通过查找:
排除与时间相关联的数字。
('b)
是必需的,因为+
的贪心行为。为了确保forward计算整数'b
是必需的。
或者根据你的编辑:
string text = "Monday 11:30am,11 v 2,3 v 4,5 v 6";
var result = Regex.Replace(text, @"(('b)(['d]+)('b)(?![:]))", new MatchEvaluator(
delegate(Match m)
{
return "Team" + m.Value; /*take value and find the proper team;*/
} ));
你最初的问题读起来好像你想要固定的"Teamnn"
格式的输出,但是你的编辑显著地改变了这一点,这样你就想用球队的名字来代替。
首先要做的是定义从队号到队名的查找。我在这里使用了一个"平凡的"1类的简单数组,但是您可以选择任何东西来存储它们,如果数字足够大,甚至可以选择数据库,尽管我怀疑这里的情况是否如此。重要的是它是一个查找表。
class Team
{
public string Id { get; set; }
public string Name { get; set; }
}
static Team[] teams = {
new Team { Id = "11", Name = "Hurricanes" },
new Team { Id = "2", Name = "Team abc" },
new Team { Id = "3", Name = "Vipers" },
new Team { Id = "4", Name = "Dodgers" },
new Team { Id = "1", Name = "Frozen Rope" },
};
现在定义模式匹配。正则表达式
Regex regex = new Regex(@"('d+)'s*v's*('d+)");
将匹配:
-
('d+)
-一个数字序列,并捕获它以替换后面的 -
's*
-可能有空格 -
v
-字母v -
's*
-可能有更多的空间 -
('d+)
-另一个数字序列,并捕获它以替换后面的
注意,两个数字序列——球队号码——将被捕获。由于。net中的正则表达式的工作方式,此fixture的整个字符串将被捕获为组0,第一个队号将是组1,第二个队号将是组2。
public string Test()
{
string text = "Monday 11:30am,11 v 2,3 v 4";
foreach (Match match in regex.Matches(text))
{
// For the first team in the fixture:
string team1Id = match.Groups[1].Value; // get the id from the text
Team team1 = teams.FirstOrDefault(t => t.Id == team1Id); // look it up
string team1Name = team1.Name; // get the team name
// For the second team in the fixture:
string team2Id = match.Groups[2].Value; // get the id from the text
Team team2 = teams.FirstOrDefault(t => t.Id == team2Id); // look it up
string team2Name = team2.Name; // get the team name
// Replace the whole matched string (with numbers)...
string fixtureWithNumbers = match.Groups[0].Value;
// ... with the equivalent with team names.
string fixtureWithNames = team1Name + " v " + team2Name;
text = text.Replace(fixtureWithNumbers, fixtureWithNames);
}
return text;
}
这是手写的。当然,你可以把它缩小一点,像这样:
public string Test2(string text)
{
foreach (Match m in Regex.Matches(text, @"('d+)'s*v's*('d+)"))
{
text = text.Replace(match.Groups[0].Value,
teams.FirstOrDefault(t => t.Id == m.Groups[1].Value)
.Name +
" v " +
teams.FirstOrDefault(t => t.Id == m.Groups[2].Value)
.Name);
}
return text;
}
虽然没有真正的好处,而且可能以一点可读性和可维护性为代价,但这些商品往往被低估了。
另一种方法是替换foreach
循环,并通过MatchEvaluator
在Regex
类中进行循环。(我要感谢Dalorzo提出的这个方法)。为此,我将正则表达式更改为((?<T>'d+)(?='s*v))|((?<=v's*)(?<T>'d+))
:
-
(?<T>'d+)
-一个数字序列,并捕获它作为命名项(T)以替换后面的 -
(?='s*v)
-后面跟着一些(或没有)空格和字母v
-
|
-or- -
(?<=v's*)
-前面有一个字母v
,后面有一些空白 -
(?<T>'d+)
-一个数字序列,并捕获它作为命名项(T)以替换后面的
前向和后向表达式假设名称或日期永远不会以字母v结束(在英语中是这样,至少在一些其他语言中可能是这样,但不一定在所有语言中都是这样),但同时允许在团队号码之间存在大于v
的变量空白。如果空白是固定的,那么就可以用来改进字符串的前向和后向。
这里的另一个变化是,我从之前创建的数组中创建了一个Dictionary
,只有当团队数量变得相对较大时才会产生明显的影响。可见的效果是一个简单的字典查找,而不是对每个团队的数组进行线性扫描。
static Dictionary<string, string> teamDb =
teams.ToDictionary(t => t.Id, t => t.Name);
public static void Test3(string text)
{
var result = Regex.Replace(text,
@"((?<T>'d+)(?='s*v))|((?<=v's*)(?<T>'d+))",
new MatchEvaluator(
m => teamDb[m.Groups["T"].Value]
));
Console.WriteLine("Test3: {0}", result);
}
在这三种情况下,如果输入字符串包含一个没有出现在查找表中的球队编号,代码仍然有一个未解决的问题(当试图获得Name
时,程序将因NullReferenceException
而崩溃),但是解决这个问题需要决定在输出字符串中放入什么,如果发生这种情况。
,
1没有微不足道的程序