我有一个Perl脚本,它从C源文件中构建一个长度超过X个字符的符号散列,然后替换为A[0-9]{5}
字符串。该数字随着每个要缩短的连续符号而递增。这是为了准备要在非常旧的编译器上编译的代码,这些编译器对符号的长度有奇怪的限制。
在Pulling a sed script into a perl program中,我能够将旧的外部sed脚本方法转换为直接在Perl中工作(大部分)。现在的问题是我收到一个投诉
Use of uninitialized value within %transformations in substitution iterator at src/misc/snavig.pl line 210, <> line 8.
字符串
约1600次。问题出在这段代码中,它应用了替换:
my $oldsymbols = join '|', keys %transformations;
my $oldfilenames = join '|', keys %includes;
local $^I = '.bak';
local @ARGV = glob("*.c *.h");
while (<>) {
s/\b($oldsymbols)\b/$transformations{$1}/g;
s/($oldfilenames)/$includes{$1}/g;
print;
}
型%transformations
哈希看起来像这样:
hide_lines => 'A00058'
message => 'A00165'
tokenise_text => 'A00388'
z_print_addr => 'A00220'
z_ret_popped => 'A00236'
encode_text => 'A00384'
型
我已经追踪到整行替换匹配的第一部分,它被放入$1
中。因此,compression_names[compression_mode], hide_lines);
当然不会在该哈希中作为键出现。我不明白的是如何保护$oldfilenames
字符串,使$1
只接收该字符串中的一个符号。%includes
中的替换不会引起抱怨,因为整行始终匹配一个键。
我不记得我在哪里找到了一个建议,用\K ... (?=.)
或\K ... (?=.*)
来保护它,无论是在\b
的内部还是外部。他们要么什么也没做,要么把事情搞砸了。什么是正确和有效的方法来摆脱这些抱怨?
编辑以添加示例数据:
处理前:
/*
* print_char
*
* High level output function.
*
*/
void print_char(zchar c)
{
static bool flag = FALSE;
need_newline_at_exit = TRUE;
if (message || ostream_memory || enable_buffering) {
if (!flag) {
/* Characters 0 and ZC_RETURN are special cases */
if (c == ZC_RETURN) {
new_line();
return;
}
型
加工后:
/*
* A00267
*
* High level output function.
*
*/
void A00267(zchar c)
{
static bool flag = FALSE;
A00174 = TRUE;
if (A00165 || A00162 || A00173) {
if (!flag) {
/* Characters 0 and ZC_RETURN are special cases */
if (c == ZC_RETURN) {
A00266();
return;
}
型
在注解掉的区域内进行替换是可以的。
2条答案
按热度按时间vbkedwbf1#
您的帖子中缺少信息,或者某些信息不正确。(如果这不能回答您的问题,您需要提供问题的实际演示。
我猜问题是你的钥匙上有特殊符号。例如,假设您有一个名为
foo*
的键。这将匹配foo
(以及其他),这可能不在您的散列中。您可以通过添加以下内容来验证是否存在此问题:
字符串
如果这是故意的,你可以替换
型
与
型
但请注意,如果键以非单词字符开始或结束,则锚定
\b
的行为将不符合预期。0wi1tuuw2#
我已经追踪到整行替换匹配的第一部分,它被放入$1。
你的正则表达式并不匹配完整的行,除非你的真实的代码中有一些你没有给我们看的东西。
我不觉得运行这个有什么问题
字符串
它做了正确的事
型
你能更新一下问题吗?