【问题标题】:Is there a truly universal wildcard in Grep? [duplicate]Grep 中是否存在真正通用的通配符? [复制]
【发布时间】:2009-12-13 19:04:05
【问题描述】:

这里是非常基本的问题。所以我被告知一个点。匹配除换行符以外的任何字符。我正在寻找与任何字符匹配的内容,包括换行符。

我要做的就是在两个特定字符串之间捕获网站页面中的所有文本,去除页眉和页脚。诸如 HEADER TEXT(.+)FOOTER TEXT 之类的东西,然后提取括号中的内容,但我找不到在页眉和页脚之间包含所有文本和换行符的方法,这有意义吗?提前致谢!

【问题讨论】:

    标签: regex bbedit


    【解决方案1】:

    当我需要匹配多个字符(包括换行符)时,我会这样做:

    [\s\S]*?
    

    注意我使用的是非贪婪模式

    【讨论】:

    • 谢谢大家!多么友好,有用的网站。我忘了提到我在 BBEdit 中使用 grep 搜索,这非常有效。你们都摇滚!
    【解决方案2】:

    你可以用 Perl 做到这一点:

    $ perl -ne 'print if /HEADER TEXT/ .. /FOOTER TEXT/' file.html
    

    要仅打印分隔符之间的文本,请使用

    $ perl -000 -lne 'print $1 while /HEADER TEXT(.+?)FOOTER TEXT/sg' file.html
    

    /s 开关使正则表达式匹配器将整个字符串视为s单行,这意味着点匹配换行符,/g 意味着匹配尽可能多的次数。 p>

    上面的示例假设您正在处理本地磁盘上的 HTML 文件。如果您需要先获取它们,请使用 get from LWP::Simple:

    $ perl -MLWP::Simple -le '$_ = get "http://stackoverflow.com";
                              print $1 while m!<head>(.+?)</head>!sg'
    

    请注意,使用上述正则表达式解析 HTML 在一般情况下不起作用!如果您正在使用快速且脏的扫描仪,很好,但对于需要为了更健壮,请使用真正的解析器。

    【讨论】:

      【解决方案3】:

      根据定义,grep 查找匹配的行;它读取一行,查看它是否匹配,然后打印该行。

      使用sed

      sed -n '/HEADER TEXT/,/FOOTER TEXT/p' "$@"
      

      这将从匹配'HEADER TEXT'的第一行打印到匹配'FOOTER TEXT'的第一行,然后迭代; “-n”停止默认的“打印每一行”操作。如果页眉和页脚文本出现在同一行,这将无法正常工作。

      要做你想做的事,我可能会使用perl(但如果你愿意,你可以使用Python)。我会考虑 slurping 整个文件,然后使用适当限定的正则表达式来查找文件的匹配部分。然而,'@gbacon' 给出的 Perl 单行语句几乎是上面 'sed' 脚本的 Perl 音译,比 slurping 更简洁。

      【讨论】:

        【解决方案4】:

        grep 的手册页说:

        grep, egrep, fgrep, rgrep - 打印匹配模式的行

        grep 不是为匹配多行而设计的。您应该尝试使用perlawk 来解决此任务。

        【讨论】:

          【解决方案5】:

          由于它被标记为“bbedit”并且 BBedit 支持 Perl 样式的模式修饰符,因此您可以允许点与开关 (?s) 匹配换行符

          (?s).

          将匹配任何字符。是的, (?s).+ 将匹配整个文本。

          【讨论】:

            【解决方案6】:

            正如其他地方所指出的,grep 将适用于单行内容。

            对于多行(在带有 Regexp::MULTILINE 的 ruby​​ 中,或者在 python、awk、sed 等中),“\s”也应该捕获换行符,所以

            HEADER TEXT(.*\s*)FOOTER TEXT 
            

            可能会工作......

            【讨论】:

            • 您必须以将多行扫描到内存中的模式读取文件才能正常工作。
            • 谢谢,我添加了你将如何在 Ruby 中做到这一点。 IIRC,那是 perlish 中的 /g,不是吗?
            【解决方案7】:

            如果你有的话,这里有一种使用 gawk 的方法

            awk -vRS="FOOTER" '/HEADER/{gsub(/.*HEADER/,"");print}' file
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-08-29
              • 1970-01-01
              • 2018-09-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-04-22
              • 1970-01-01
              相关资源
              最近更新 更多