【问题标题】:Perl Regex Trying to read macros in my commentsPerl Regex 尝试在我的评论中读取宏
【发布时间】: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 -->
  1. 评论的开头(必须在文件的第一列)
  2. 字符串IF:
  3. 可选字符串NOT(如果存在则捕获#1)
  4. 属性名称(捕获 #2)
  5. 可选等号
  6. 属性值(捕获 #3)
  7. 如果这是 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;

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    我将“一个或多个”量词添加到(?:=\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`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 2021-03-20
      • 2021-09-19
      • 1970-01-01
      • 2021-10-02
      • 2014-09-05
      • 2022-11-20
      相关资源
      最近更新 更多