【发布时间】:2014-08-08 20:14:33
【问题描述】:
我有一个程序将命令嵌入到 XML 文件、属性文件和其他文件的 cmets 中。我认识三种不同类型的 cmets:
- Perl 和 Shell 脚本 cmets(以
#开头的行) - Python 和 Java 样式的 cmets(以
//开头的行) - XML 样式 cmets(行以
<--开头,以-->结尾
我有一个 IF 宏,如果一个属性被设置为一个特定的值,我要么注释掉以下所有行,直到我得到一个嵌入的 `ENDIF,要么不理会它们。
这是一个例子:
# IF: MACHINE = SERVER
# SERVER_PORT = 1022
# ENDIF:
这是一个类似的 XML 格式示例:
<!-- IF: NOT MACHINE SERVER -->
<server>foo.vegicorp.com</server>
<!-- ENDIF: -->
我需要捕捉的内容:
1. 2. 3. 4. 5. 6. 7.
| | | | | | |
<!-- IF: NOT MACHINE = SERVER -->
- 评论的开头(必须在文件的第一列)
- 字符串
IF: - 可选字符串
NOT(如果存在则捕获#1) - 属性名称(捕获 #2)
- 可选等号
- 属性值(捕获 #3)
- 如果这是 XML 行,则可选结束注释
不知何故,我只是没有正确选择正则表达式。这是我所拥有的:
$if_line_re = qr@^(?:<\!--|#|//)\s*IF:\s+(?:(NOT)\s+)?(\S+)\s+(?:=\s)?(\S+)(?:\s*-->)?@i;
这是我的模板文件:
# Macro: machine_type choice
# Q: WHat type of machine is this?
# C: Server:SERVER
# C: Client:CLIENT
# C: A type of toaster:TOASTER
# Macro: QUESTION integer
# Q: What is an example of a number
question=%QUESTION%
machine type = %machine_type%
# IF: Machine = SERVER
machine = server
# ENDIF:
# IF: NOT MACHINE = SERVER
Machine = Toaster? Maybe Client?
# ENDIF:
# IF: Machine = Toaster
machine = Definitely a toaster!
# ENDIF:
模板的填写方式如下:
# Macro: machine_type choice
# Q: WHat type of machine is this?
# C: Server:SERVER
# C: Client:CLIENT
# C: A type of toaster:TOASTER
# Macro: QUESTION integer
# Q: What is an example of a number
question=34
machine type = TOASTER
# IF: Machine = SERVER -->
# machine = server
#
# ENDIF:
# IF: NOT MACHINE = SERVER
Machine = Toaster? Maybe Client?
# ENDIF:
# IF: Machine = Toaster
# machine = Definitely a toaster!
#
# ENDIF:
我添加了一些调试行来显示发生了什么:
DEBUG: if ( 0 and SERVER eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 0 and SERVER ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 0 and SERVER eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 0 and SERVER ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 1 and SERVER eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 1 and SERVER ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 1 and SERVER eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 1 and SERVER ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 1 and SERVER eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 1 and SERVER ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 0 and Toaster eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 0 and Toaster ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
DEBUG: if ( 0 and Toaster eq ) { at ./autoconfig.pl line 1048, <$template_fh> line 32.
DEBUG: if ( not 0 and Toaster ne ) { at ./autoconfig.pl line 1063, <$template_fh> line 32.
如您所见,我与属性匹配的值没有被拾取。我的正则表达式与该行匹配,但未捕获该属性的值。代码如下:
elsif ( $line =~ IF_LINE ) {
my $negation = $1;
my $parameter = uc $2;
my $value = $3;
my $if_clause;
if ( $negation ) {
$if_clause = If->new( $parameter, $value, 1 );
} else {
$if_clause = If->new( $parameter, $value, 0 );
}
push @macro_list, $if_clause;
【问题讨论】: