我有一个字符串,其中包含一些函数(我知道它们的名字)及其参数如下: 翻译(700 210)旋转(-30)
我想在一个字符串数组中解析它们中的每一个,以函数名开头,后跟参数。
我不太了解正则表达式,到目前为止我得到了这个:
MatchCollection matches = Regex.Matches(attribute.InnerText, @"((translate|rotate|scale|matrix)\s*\(\s*(-?\d+\s*\,*\s*)+\))*");
for (int i = 0; i < matches.Count; i++)
{
Console.WriteLine(matches[i].Value);
}
返回的是:
translate(700 210)
[blank space]
rotate(-30)
[blank space]
这对我有用,因为我可以从结果集合中的每一行运行另一个正则表达式并获取内容。我不明白的是为什么这些方法之间返回了空行。
此外,运行正则表达式两次 - 一次分离方法,一次实际解析它们是一个好方法?
谢谢!
答案 0 :(得分:2)
Regex.Matches
会多次匹配您的整个正则表达式。它找到了整个事物的一个匹配,然后找到整个事物的下一个匹配。
*
的最外面的parens表示您愿意接受前一组内容的零或更多作为匹配。因此,当它找不到它们时,它会愉快地返回它。那不是你的意图。你想要一个。
空白是无害的,但是&#34;零或更多&#34;还包括两个。考虑这个字符串,两个函数之间没有空格:
var text = "translate(700 210)rotate(-30)";
根据你提供的正则表达式,这是一场比赛。你会得到&#34;旋转&#34;和&#34; -30&#34;。如果缺少的空间是错误,请检测它并警告用户。如果您不打算这样做,请正确解析。
所以,让我们摆脱最外层的那些*
。为了便于阅读,我们还将捕获组命名为。
var matches = Regex.Matches(text, @"(?<funcName>translate|rotate|scale|matrix)\s*\(\s*(?<param>-?\s*\d+\s*\,*\s*)+\)");
foreach (Match match in matches)
{
if (match.Groups["funcName"].Success)
{
var funcName = match.Groups["funcName"].Value;
var param = Int32.Parse(match.Groups["param"].Value);
Console.WriteLine($"{funcName}( {param} )");
}
}
我在可选\s*
之后也卡在-
,以防万一。
答案 1 :(得分:0)
我喜欢将Regex与字典一起使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication56
{
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
string input = "translate(700 210) rotate(-30)";
string pattern = @"(?'command'[^\(]+)\((?'value'[^\)]+)\)";
MatchCollection matches = Regex.Matches(input, pattern);
foreach(Match match in matches.Cast<Match>())
{
dict.Add(match.Groups["command"].Value, match.Groups["value"].Value);
}
}
}
}