我输入了以下字符串:
"Monday 11:30am,11 v 2,3 v 4"
我需要替换:
11
与Hurricanes
2
与Team abc
3
与Vipers
4
与Dodgers
1
与Frozen Rope
依旧......
但我不想在1
中两次替换11
。
我显然没有掌握正则表达式。但我试过这样的事情:
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"
答案 0 :(得分:3)
试试这个正则表达式:
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的匹配。
答案 1 :(得分:1)
这应该可以解决问题:
\d{1,2}
(注意最后的空字符!)
答案 2 :(得分:0)
来自http://msdn.microsoft.com/en-us/library/20bw873z(v=vs.110).aspx,似乎与其他语言中的正则表达式语法大致相符,您可以使用" \ d +"匹配一个或多个十进制数字。
我没有为你构建整个正确的正则表达式,因为你的问题只是匹配给定的单一模式(11而不是1)。
答案 3 :(得分:0)
您的初始问题就像是想要输出"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
循环,并通过Regex
在MatchEvaluator
类中完成循环。 (感谢Dalorzo建议采用这种方法)。为此,我将正则表达式更改为((?<T>\d+)(?=\s*v))|((?<=v\s*)(?<T>\d+))
:
(?<T>\d+)
- 一系列数字,并将其捕获为命名项目(T)以便稍后替换(?=\s*v)
- 后面跟着一些(或没有)空格和一个字母v
|
- 或 - (?<=v\s*)
- 前面有一个字母v
,后跟一些(或没有)空格(?<T>\d+)
- 一系列数字,并将其捕获为命名项目(T)以便稍后替换前瞻和后瞻表达式假设名称或一天永远不会以字母v结尾(英语为true,可能至少包含其他一些语言,但不一定全部),但同时允许变量空格要么是团队号码之间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);
}
在所有三种情况下,如果输入字符串包含未出现在查找表中的团队编号,则代码仍然存在未解决的问题(在尝试获取{{1时,程序将使用NullReferenceException
崩溃但是,解决这个问题需要决定你想要在输出字符串中放入什么。
-
1 没有一个简单的程序。
答案 4 :(得分:0)
这是我的版本:
/((\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");
<强> Online Demo 强>
\d+
会捕获尽可能多的数字
(\b)(?![:])
会通过搜索:
来排除与时间相关联的数字。
(\b)
是必需的,因为所谓的+
的贪婪行为。为了确保预先评估整数\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;*/
} ));