我有一个程序可以将命令嵌入到 XML 文件、属性文件和其他文件的注释中。我识别三种不同类型的评论:
- Perl 和 Shell 脚本注释(以
#
开头的行) - Python 和 Java 风格的注释(以
//
开头的行) - XML 样式注释(行以
<--
开始并以-->
结束
我有一个 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;
最佳答案
我将“一个或多个”量词添加到 (?:=\s)
,结果是 (?:=\s+)
:
$if_line_re = qr@^(?:<\!--|#|//)\s*IF:\s+(?:(NOT)\s+)?(\S+)\s+(?:=\s+)?(\S+)(?:\s*-->)?@i;
现在我得到:
MATCH 1
1. [9-12] `NOT`
2. [13-20] `MACHINE`
3. [23-29] `SERVER`
关于regex - Perl Regex 试图读取我评论中的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24287150/