【问题标题】:Matching XML Comments with awk使用 awk 匹配 XML 注释
【发布时间】:2014-01-13 12:32:22
【问题描述】:

对不起我的英语:(

我目前正在开发一个“bash 脚本”,该脚本对每个 xml cmets 进行处理。 它仍然是我,没有解决方案的 2 个“奇怪”问题 oO!

所以...之前,我要疯了正则表达式引用 / 未引用 / 斜线 / 因瓦...我的疯狂^^)。我是来寻求帮助的:D

我尝试了几种模式,但未能找到匹配所有情况的模式... 首先,我在这里收集了我的正则表达式所需的信息:XML Comments

[15] 评论 ::= ''

[2] 字符 ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

我已将其“翻译”为:

xmlSpaceCharSet=" \r\n\t"

xmlCharCharSet0="$xmlSpaceCharSet\x21-\x218F\\\\\\\x2C00-\\\\\\\xD7FF\\\\\\\xE000-\\\\\\\xFFFD\\\\\\\x10000-\\\\\\\x10FFFF"

xmlCharCharSet1="$xmlSpaceCharSet\x21-\xD7FF\\\\\\\xE000-\\\\\\\xFFFD\\\\\\\x10000-\\\\\\\x10FFFF"

xmlCommentPattern="<!--[^-][$xmlCharCharSet]*-->"

首先,经过一些测试,我找到了一种使用 unicode 字符定义范围而不会出现 \\\\\\\x<hex_val> 的 awk 失败的方法。但是某些范围仅适用于一个\,但不适用于\\\\\\\。此外,当范围必须以一个\ 开头时:\x21,无需像这样转义结尾:\\\\\\\xD7FF。最后(facepalm),不可能像这样定义范围:\xFF-\\\\\\\xFFFF...

巫毒#1:

测试.xml: <!-- Unicode XML Comments-[©╔ΘϘϖ] -->

test.sh: echo "$(<$1)" | awk -v regexPattern="$xmlCommentPattern" '$0 ~ regexPattern'

使用 xmlCharCharSet0 或 xmlCharCharSet1 相同的结果,不匹配,除非没有“╔ΘϘϖ”字符,匹配“©”...

巫毒#2:

test.xml:

<!-- Unicode XML Comments

MultiLine

-->

test.sh: echo "$(<$1)" | awk -v regexPattern="$xmlCommentPattern" '$0 ~ regexPattern'

使用 xmlCharCharSet0 或 xmlCharCharSet1 相同的结果,不匹配,除非没有 \n...

所以如果有人可以帮助我,一个解决方案,一些信息...... :) 我快疯了! ^^ =P

我需要查找和检查的标题示例:

<!--

User: all alpha format (latin, chinese, japan, ...)

Date: all date/time format

Last Revision: all date/time format

Revision Code: [guid]

-->

谢谢你的一切!

【问题讨论】:

  • <!-- 可能在一行中出现多次,第 90 个<!-- 可能在最后一行,这意味着您需要解析到下一个-->。因为这必须逐个字符地完成,所以我会说你使用了错误的工具来完成这项工作。解析标记应该使用适当的标记解析器来完成,而不是简单的文本处理语言,尽管 awk 本身显然并不简单。
  • 确定!但我只需要最长的匹配,并且它不禁止在 awk 正则表达式中匹配新行......如果我想解析一个 xml 文件是正确的,但我只想检查并找到一个包含在 xml 注释中的标题标签。 (我已经用一个例子更新了我的帖子)。
  • +1 是我见过的最雄心勃勃的 awk 正则表达式使用。你看过home.vrweb.de/~juergen.kahrs/gawk/XML 吗? (我希望这仍然是一个实时链接,否则在网上寻找 xgawk。)。最后,您是否在 xmlstarlet 上进行了搜索。祝你好运。
  • 大声笑 ^^ ;p 不幸的是,我的解决方案必须没有额外的二进制文件...只有脚本 =/
  • xmlCommentPattern="<!--[^-][$xmlCharCharSet]*-->"$xmlCharCharSet 是什么? (你定义了$xmlCharCharSet0$xmlCharCharSet1,但是我看不到你定义了$xmlCharCharSet..)

标签: xml regex bash unicode awk


【解决方案1】:

像 awk 和 sed 这样的行编辑器是处理 XML 的糟糕选择。我会推荐使用xmllint,它可以使用XPath 表达式来解析XML 文档。

示例

data.xml

<data>
  <!--
  ==================
  First row
  Mulit-line comment
  ==================
  -->
  <row>
    <col1>one</col1>
    <col2>two</col2>
    <col3>three</col3>
  </row>
  <!--
  ==================
  Second row
  Mulit-line comment
  ==================
  -->
  <row>
    <col1>une</col1>
    <col2>duex</col2>
    <col3>trois</col3>
  </row>
</data>

检索 cmets

使用 Xpath 表达式检索第一条评论:

$ xmllint --xpath "/data/comment()[1]" data.xml
<!--
  ==================
  First row
  Mulit-line comment
  ==================
  -->

第二条评论也是这样

$ xmllint --xpath "/data/comment()[2]" data.xml
<!--
  ==================
  Second row
  Mulit-line comment
  ==================
  -->

【讨论】:

  • 感谢您的回答...但不幸的是,就像我已经说过的那样,我的解决方案必须没有额外的二进制文件...只有脚本 =/ 但是解析 XML 的好方法!
  • @user3134484 awk 是一个额外的二进制文件 :-) 这就是我一开始所说的,在 bash 中这样做很糟糕。在关闭 xmllint 之前,请检查它是否已安装在您的系统上(默认情况下安装在 Ubuntu 上)。
  • 当然这是一个额外的二进制文件。但是安装在 AIX 系统上;)我认为不是 xmllint 的情况。而且自 10 年以来安装的服务器肯定不是这种情况......我不想让我的问题复杂化......我别无选择。
  • @MarkO'Connor 与 sed 不同,awk 不是“行编辑器”。 awk 处理记录。默认情况下,一条记录是一行,但它可以是您想要定义的任何多行或部分行文本块。
【解决方案2】:

您可以尝试以下方法:

awk -f c.awk test.xml

c.awk 在哪里:

{
    line=line $0 RS
}
END {
    regex="<!--(.|(.?(-[^>]|[^-][^>]|[^-]>)*))->"
    while (match(line,regex)) {
        print ++i ": \"" substr(line,RSTART,RLENGTH) "\""
        line=substr(line,RSTART+RLENGTH)
    }
}

test.xml 是你的输入文件。

我用这个文件试了一下:

<!-- Unicode XML Comments-[©╔ΘϘϖ] -->
<!-- Unicode XML Comments

MultiLine

-->
aa


    <!--

    User: all alpha format (latin, chinese, japan, ...)

    Date: all date/time format

    Last Revision: all date/time format

    Revision Code: [guid]

    -->

有输出:

1: "<!-- Unicode XML Comments-[©╔ΘϘϖ] -->"
2: "<!-- Unicode XML Comments

MultiLine

-->"
3: "<!--

    User: all alpha format (latin, chinese, japan, ...)

    Date: all date/time format

    Last Revision: all date/time format

    Revision Code: [guid]

    -->"

【讨论】:

  • 非常感谢!我目前正在测试中......但现在没有打印出来:(我正在为我的测试使用 cygwin......也许是这样......
  • 大声笑......愚蠢......我一直在用 XML 复制你的输出......(facepalm)......所以它的工作!!!!!!!!!泰!!!!!!! ^^你帮我省去繁琐的工作^^
【解决方案3】:

新测试后,我只能用一个括号范围匹配新行。如果我在括号之前或之后添加一些字符,则正则表达式与新行不匹配... oO unicode 字符没有进展...

用于匹配新行的模式:“[a-zA-Z0-9\n]+”。

【讨论】:

    猜你喜欢
    • 2013-05-23
    • 2011-06-15
    • 1970-01-01
    • 2013-02-12
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多