2014-10-18 62 views
0

我正在尝试为我的服务编写一个迷你类型的脚本语言,并且我一直试图从某行中的某些字符串中提取数据。例如:使用RegularExpressions解析并执行方法

!d3 Profile: {D3Api("Name")} !weather Current Weather {Weather("Location")}

与我当前的代码工作,我似乎无法得到它找到我要找的文本。如果该行包含说{D3Api()}{Weather()}的权利,我大概可以做一个if声明?无论如何,这是我对在查找文本{D3Api()}和检索文字表达:

​​

它不解析或返回文本。我该如何改进?

我的设计很差的解析代码:

public static void Main(string[] args) { 
    string t = "{D3Api(\"Name\")"; 
    String text = "(\\{D3Api\\(\"(.*?)\"\\)\\})"; 
    Regex r = new Regex(text, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
    Console.WriteLine("Parsing..\n\r"); 
    Match m = r.Match(t); 
    if (m.Success) { 
      string c = m.Groups[1].ToString(); 
      string s = m.Groups[2].ToString(); 
      Console.Write("(" + c.ToString() + ")" + "(" + s.ToString() + ")" + "\n"); 
    } 
    Console.ReadLine(); 
} 

回答

1

我不是100%确定,如果我真的回答你的问题,但我认为你看起来有命名组。这是用(?<function>[a-zA-Z0-9]+)\((?<param>[^)]\)这样的正则表达式来完成的。有了这个,你可以为你的函数名称设置一个通用格式并且只需要一个参数。有关已命名组的更多信息,请参阅here

顺便说一句,如果您的语言比较复杂,那么您可能会发现RegEx不足以满足您的需求。在这种情况下,我建议看看使用EBNF创建自定义语法,然后创建一个标记器(非常有趣的项目IMO)。可以看到一个例子:here

+0

这就是我一直在寻找的东西,EBNF似乎是我想要完成的最合适的!谢谢! – 2014-10-18 19:03:23

0

您不使用量词。您可以使用*这意味着匹配以前的令牌0或更多次。

String text = "(\\{D3Api\\(\"(.*?)\"\\)\\})"; 
Regex r = new Regex(text , RegexOptions.IgnoreCase | RegexOptions.Singleline); 

做好以上后,你可以,如果你想多场比赛做使用Regex.MatchMatches

+0

它在我的正则表达式测试程序中没有显示任何匹配。我可以错过令牌吗?我试图在'{D3Api(“Name”)}'中获得'Name'参数。我添加了解析器代码以反映您的答案。 – 2014-10-18 18:07:43

+0

@BrandonPalmer http://regex101.com/r/qJ1hX7/1。我在c#中使用了''''和'\',因为这是必要的。 – 2014-10-19 03:58:57

+0

谢谢先生!但是我决定使用“反讽”,并为这种类型的东西制作自己的语言new Command(“Hello this is the API {D1}“,D3Api(String)); – 2014-10-20 14:33:18