关于正则表达式,我是一个完整的新词,并希望帮助使表达式符合以下内容:
{ValidFunctionName}({parameter}:"{value}")
{ValidFunctionName}({parameter}:"{value}",
{parameter}:"{value}")
{ValidFunctionName}()
{x}是我要匹配的地方,{parameter}可以是任何$%“$例如$ {value}必须用引号括起来。
ThisIsValid_01(a:"40")
将是“ThisIsValid_01”,“a”,“40”
ThisIsValid_01(a:"40", b:"ZOO")
将是“ThisIsValid_01”,“a”,“40”,“b”,“ZOO”
01_ThisIsntValid(a:"40")
不会返回任何内容
ThisIsntValid_02(a:40)
不会返回任何内容,因为40未用引号括起来。
ThisIsValid_02()
将返回“ThisIsValid_02”
对于我遇到的有效函数名称:“[A-Za-z _] [A-Za-z_0-9] *” 但我不能为我的生活弄清楚如何匹配其余的。 我一直在http://regexpal.com/上玩,试图获得所有条件的有效匹配,但无济于事:(
如果你也很好地解释了正则表达式会很好,所以我可以学习:)
答案 0 :(得分:2)
编辑:这将有效,使用2个正则表达式。第一个获取函数名称及其中的所有内容,第二个从函数括号内的内容中提取每对参数和值。单个正则表达式无法做到这一点。为空格添加一些[ \t\n\r]*
。
Regex r = new Regex(@"(?<function>\w[\w\d]*?)\((?<inner>.*?)\)");
Regex inner = new Regex(@",?(?<param>.+?):""(?<value>[^""]*?)""");
string input = "_test0(a:\"lolololol\",b:\"2\") _test1(ghgasghe:\"asjkdgh\")";
List<List<string>> matches = new List<List<string>>();
MatchCollection mc = r.Matches(input);
foreach (Match match in mc)
{
var l = new List<string>();
l.Add(match.Groups["function"].Value);
foreach (Match m in inner.Matches(match.Groups["inner"].Value))
{
l.Add(m.Groups["param"].Value);
l.Add(m.Groups["value"].Value);
}
matches.Add(l);
}
(?<function>\w[\w\d]*?)\((?<param>.+?):"(?<value>[^"]*?)"\)
让我们删除群组抓取,以便更容易理解:\w[\w\d]*?\(.+?:"[^"]?"\)
\w
是单词class,它是[a-zA-Z_]
的缩写
\d
是数字类,它是[0-9]
\w[\w\d]*?
确保函数开头有有效的单词字符,然后匹配零个或多个字或数字字符。
\(.+?
匹配左括号,然后匹配一个或多个任何字符(参数)
:"[^"]*?"\)
匹配一个冒号,然后是开头的引号,然后是零或更多的除引号之外的任何字符(对于值),然后是关闭引号和右括号。
使用反斜杠将转义的方括号(或某些人称之为parens),因为否则它们会捕获组。
(?<name> )
会捕获一些文字。
每个?
和*
运算符之后的+
使它们非贪婪,这意味着它们将匹配最少,而不是最多,文字数量。
Regex r = new Regex(@"(?<function>\w[\w\d]*?)\((?<param>.+?):""(?<value>[^""]*?)""");
string input = "_test0(aa%£$!:\"lolololol\") _test1(ghgasghe:\"asjkdgh\")";
List<string[]> matches = new List<string[]>();
if(r.IsMatch(input))
{
MatchCollection mc = r.Matches(input);
foreach (Match match in mc)
matches.Add(new[] { match.Groups["function"].Value, match.Groups["param"].Value, match.Groups["value"].Value });
}
编辑:现在你已经添加了一个未定义数量的多个参数,我建议你自己创建解析器,而不是使用正则表达式。上面的例子只适用于一个参数,严格来说没有空格。这将使用严格的空格匹配多个参数,但不会返回参数和值:
\w[\w\d]*?\(.+?:"[^"]*?"(,.+?:"[^"]*?")*\)
只是为了好玩,就像上面一样,但是有了空白:
\w[\w\d]*?[ \t\r\n]*\([ \t\r\n]*.+?[ \t\r\n]*:[ \t\r\n]*"[^"]*?"([ \t\r\n]*,[ \t\r\n]*.+?[ \t\r\n]*:[ \t\r\n]*"[^"]*?")*[ \t\r\n]*\)
捕获你想要的文本会很难,因为你不知道你将拥有多少个捕获,因此这些正则表达式是不合适的。
答案 1 :(得分:1)
试试这个:
^\s*(?<FunctionName>[A-Za-z][A-Za-z_0-9]*)\(((?<parameter>[^:]*):"(?<value>[^"]+)",?\s*)*\)
^\s*(?<FunctionName>[A-Za-z][A-Za-z_0-9]*)
匹配函数名称,^表示行的开头,因此字符串中的第一个字符必须匹配。如果你不需要它,你可以让你删除空格捕获,我只是添加它以使匹配更灵活。\(((?<parameter>[^:]*):"(?<value>[^"]+)",?)*\)
表示捕获括号内的每个参数 - 值对。您必须转义函数的括号,因为它们是正则表达式语法中的符号。 ?&lt;&gt;括号内部被命名为捕获组,当它们被库支持时,它们在.NET中,可以更轻松地抓取匹配中的组。
答案 2 :(得分:1)
答案 3 :(得分:1)
其他人已经给出了一个答案,给出了一个简单的字符串列表,但为了强类型和正确的类结构,我将提供一个正确封装数据的解决方案。
首先,声明两个类:
public class ParamValue // For a parameter and its value
{
public string Parameter;
public string Value;
}
public class FunctionInfo // For a whole function with all its parameters
{
public string FunctionName;
public List<ParamValue> Values;
}
然后进行匹配并填充FunctionInfo
s:
(顺便说一下,我对正则表达式进行了一些修改......它现在将正确匹配标识符,并且它不会将双引号作为每个参数的“值”的一部分。)< / p>
Regex r = new Regex(@"(?<function>[\p{L}_]\w*?)\((?<inner>.*?)\)");
Regex inner = new Regex(@",?(?<param>.+?):""(?<value>[^""]*?)""");
string input = "_test0(a:\"lolololol\",b:\"2\") _test1(ghgasghe:\"asjkdgh\")";
var matches = new List<FunctionInfo>();
if (r.IsMatch(input))
{
MatchCollection mc = r.Matches(input);
foreach (Match match in mc)
{
var l = new List<ParamValue>();
foreach (Match m in inner.Matches(match.Groups["inner"].Value))
l.Add(new ParamValue
{
Parameter = m.Groups["param"].Value,
Value = m.Groups["value"].Value
});
matches.Add(new FunctionInfo
{
FunctionName = match.Groups["function"].Value,
Values = l
});
}
}
然后,您可以使用FunctionName
:
foreach (var match in matches)
{
Console.WriteLine("{0}({1})", match.FunctionName,
string.Join(", ", match.Values.Select(val =>
string.Format("{0}: \"{1}\"", val.Parameter, val.Value))));
}
答案 4 :(得分:0)
对于类似的问题,我总是建议人们不要“找到”单个正则表达式,而是编写多个正则表达式共享工作。
但这是我的快速镜头:
(?<funcName>[A-Za-z_][A-Za-z_0-9]*)
\(
(?<ParamGroup>
(?<paramName>[^(]+?)
:
"(?<paramValue>[^"]*)"
((,\s*)|(?=\)))
)*
\)
空白是为了更好的可读性。删除它们或设置忽略模式空格的选项。
答案 5 :(得分:0)
此正则表达式传递了所有测试用例:
^(?<function>[A-Za-z][\w]*?)\(((?<param>[^:]*?):"(?<value>[^"]*?)",{0,1}\s*)*\)$
这适用于多个参数,没有参数。它还处理param名称中的特殊字符和逗号后面的空格。可能需要进行一些调整,因为您的测试用例不包括您在文本中指明的所有内容。
请注意,\w
通常包含数字,不适合作为函数名称的前导字符。参考:http://www.regular-expressions.info/charclass.html#shorthand