正则表达式模式重复和捕获

时间:2013-07-31 05:49:06

标签: regex notepad++

我最近不得不在C#中翻译propkeys.h(在C [++]?中)。

我的目标是来自:

DEFINE_PROPERTYKEY(PKEY_Audio_ChannelCount, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 7);

要:

public static PropertyKey Audio_ChannelCount = new PropertyKey(new Guid("{64440490-4C8B-11D1-8B70-080036B11A03}"));

我正在使用Notepad ++作为正则表达式,但我对任何其他可编写脚本的解决方案(perl,sed ......)持开放态度。请不要编译语言(如C#,Java ......)。

我最终得到了这个(工作):

// TURNS GUID into String
// Find what (Line breaks inserted for convenience):
0x([[:xdigit:]]{8}),\s*0x([[:xdigit:]]{4}),\s*0x([[:xdigit:]]
{4}),\s*0x([[:xdigit:]]{2}),\s*0x([[:xdigit:]]{2}),\s*0x([[:xdigit:]]
{2}),\s*0x([[:xdigit:]]{2}),\s*0x([[:xdigit:]]{2}),\s*0x([[:xdigit:]]
{2}),\s*0x([[:xdigit:]]{2}),\s*0x([[:xdigit:]]{2})

// Replace with:
new Guid\("{$1-$2-$3-$4$5-$6$7$8$9$10$11}"\)

// Final pass
// Find what:
^DEFINE_PROPERTYKEY\(PKEY_(\w+),\s*(new Guid\("\{[[:xdigit:]|\-]+"\)),\s*\d+\);$
// Replace with:
public static PropertyKey $1 = new PropertyKey\($2\);

虽然这是有效的,但我觉得第一次传递的东西很奇怪。我想用一个重复的替换吨{2}。 类似的东西:

(0x([[:xdigit:]]){2},\s*)+

但无法让它与群体合作。有人可以用正则表达式告诉我一种“标准”的方法吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,当您使用量词执行匹配时,该组将匹配整个文本,因此更“优雅”的解决方案是使用等效于perl的\ G元字符,它在上一个匹配结束后开始匹配。你可以使用这样的东西(Perl):

my $text = "DEFINE_PROPERTYKEY(PKEY_Audio_ChannelCount, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 7);";
my $res = "public static PropertyKey Audio_ChannelCount = new PropertyKey(new Guid(\"{";

if($text =~ m/0x((?:\d|[A-F]){8}),\s*0x((?:\d|[A-F]){4}),\s*0x((?:\d|[A-F]){4})/gc)
{
   $res .= $1 . "-" . $2 . "-" . $3 . "-";
}

if($text =~ m/\G,\s*0x((?:\d|[A-F]){2}),\s*0x((?:\d|[A-F]){2})/gc)#
{
   $res .= $1 . $2 . "-";
}

while($text =~ m/\G,\s*0x((?:\d|[A-F]){2})/gc)
{
   $res .= $1;
}

$res .= "}\"))";

print $res . "\n";

之后你应该在$ res上有结果字符串。运行此脚本时的输出是:

public static PropertyKey Audio_ChannelCount = new PropertyKey(new Guid("{64440490-4C8B-11D1-8B70-080036B11A03}"))

免责声明:我不是Perl程序员,所以如果此代码中有任何实质性错误,请随时更正