【问题标题】:sed and it's regex for optional symbolssed 它是可选符号的正则表达式
【发布时间】:2015-05-21 17:06:39
【问题描述】:

我正在编写一个脚本,用于根据提示列表将大的 FLAC 音频文件分割成小块。我使用 cueprint 来确定标签信息,但在某些情况下它不能提供我需要的信息,我需要使用 sed 直接从 cue 文件中挖掘信息。现在我正在和 GENRE 作斗争。它的问题在于它以不同的方式出现:

REM GENRE "Gothic"
REM GENRE Gothic

似乎都符合标准,但很难解析。 对于第二种情况,类似于

sed -nr -e "s/^(REM GENRE )(.*)\r/\2/p" *.cue

完美运行并按预期返回哥特式。但是对于第一种情况,返回“哥特式”,这不是我不会穿羽毛处理的。 好吧,你会说“在正则表达式的第一部分和第三部分使用“可选”引号,就像这样

sed -nr -e "s/^(REM GENRE \"?)(.*)\"?\r/\2/p" *.cue

但这并没有按预期工作,结果是

Gothic"

尾随双引号。

任何想法如何用 sed 解析带引号和不带引号的字符串?

【问题讨论】:

    标签: regex sed


    【解决方案1】:

    sed 贪婪匹配。当你匹配(.*)"?时,.*匹配Gothic""?匹配一个空字符串。您必须从 .* 字符串中排除双引号,例如

    sed -nr 's/^REM GENRE "?([^"]*)"?\r?/\1/p' *.cue
    

    请注意,这将导致包含引号的带引号的字符串出现问题,例如"Goth\"ic"。为了避免这个问题,需要大一点的枪。我建议

    sed -nr '/^REM GENRE "?(([^"]|\\")*)"?\r?/ { s//\1/; s/\\"/"/g; p; }'
    

    那是

    /^REM GENRE "?(([^"]|\\")*)"?\r?/ {   # if a line contains the pattern
      s//\1/                              # isolate the capturing group
      s/\\"/"/g                           # unescape quotes
      p                                   # then print.
    }
    

    注意正则表达式中匹配非引号字符和转义引号的([^"]|\\")*

    【讨论】:

    • 非常好。但不适用于引用的单词:REM GENRE "Gothic" "word"
    • 确实如此。 cueprint 格式是否允许这种事情?
    • 好吧,我不认为像“哥特式”“摇滚”这样的东西在那种情况下是“可预期的”,我什至不认为像 Goth\"ic 这样的东西我会看到在那里。所以,两个建议的答案都可以完美地工作。
    【解决方案2】:

    把中间的(.*)改成([^\"]*),去掉引号。

    【讨论】:

      【解决方案3】:

      你可以用这个,

      sed -nr -e 's/^(REM GENRE )"?([^"\r]*)/\2/p' *.cue
      

      【讨论】:

        猜你喜欢
        • 2014-07-31
        • 2018-04-03
        • 1970-01-01
        • 1970-01-01
        • 2018-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-01
        相关资源
        最近更新 更多