好吧,我已经阅读了tutorials,并且为了能够清楚地看清楚我的头脑太乱了。
我正在尝试从函数签名中捕获参数及其类型信息。所以给出这样的签名:
function(/*string*/a,b,c)
我想得到这样的部分:
type: string
param:a
param:b
param:c
这也是好的:
type: string
param:a
type: null (or whitespace)
param:b
type: null (or whitespace)
param:c
所以我提出了这个正则表达式,它正在做重复捕获的常见错误(我明确捕获已开启):
function\(((\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*\)
问题是,我无法纠正错误。 :(。请帮忙!
答案 0 :(得分:3)
通常,您需要两个步骤来获取所有数据 首先,匹配/验证整个功能:
function\((?<parameters>((\/\*[a-zA-Z]+\*\/)?[0-9a-zA-Z_$]+,?)*)\)
请注意,现在您拥有一个包含所有参数的parameters
组。您可以再次匹配某些模式以获取所有参数匹配,或者在这种情况下,在,
上进行拆分。
如果你正在使用.Net,那么你很幸运。 .Net保存每个组的所有捕获的完整记录,因此您可以使用该集合:
match.Groups["param"].Captures
一些注意事项:
(?<type>(\/\*[a-zA-Z]+\*\/)?)
/
没有特殊含义(C#/。Net没有正则表达式分隔符)。以下是使用捕获的示例。同样,重点是保持type
和param
之间的关系:你想要捕获空类型,这样你就不会丢失数量。
图案:
function
\(
(?:
(?:
/\*(?<type>[a-zA-Z]+)\*/ # type within /* */
| # or
(?<type>) # capture an empty type.
)
(?<param>
[0-9a-zA-Z_$]+
)
(?:,|(?=\s*\))) # mandatory comma, unless before the last ')'
)*
\)
代码:
Match match = Regex.Match(s, pattern, RegexOptions.IgnorePatternWhitespace);
CaptureCollection types = match.Groups["type"].Captures;
CaptureCollection parameters = match.Groups["param"].Captures;
for (int i = 0; i < parameters.Count; i++)
{
string parameter = parameters[i].Value;
string type = types[i].Value;
if (String.IsNullOrEmpty(type))
type = "NO TYPE";
Console.WriteLine("Parameter: {0}, Type: {1}", parameter, type);
}
答案 1 :(得分:1)
您引用的页面使用?:
进行非捕获,然后围绕其自己的组中的重复捕获。我猜他们在暗示这样的事情function\(((?:(\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*)\)
我喜欢使用http://gskinner.com/RegExr/来测试我的表达式,但它不会显示重复捕获。您可能必须在返回的任何返回结构中循环遍历结果,以查看其他非.NET语言中的值。
抱歉,我无法更加彻底地测试......答案 2 :(得分:1)
由于这个问题很活跃,已经有一段时间了,但我想我终于找到了答案。
我认为我一直在寻找与你相同的情况,但是对于PHP的使用,并且在另一篇文章中有一个答案,我发现使用\K
和\G
命令工作得很好来自PCRE。请参阅Alan Moore的回答:PHP Regular Expression - Repeating Match of a Group
我的问题是尝试提取表格中的所有单元格值,其中每行包含6位数字,20x 1位或2位数字,以及不相关的1位或2位数字。解决方案是:
<tr class="[^"]*">\s+<td>(\d{6})<\/td>|\G<\/td>[^<>]*+<td>\K\d{1,6}|<td>(\d{1,2})<\/td>
非常好的解决方案,如果我自己这样说的话!