代码之家  ›  专栏  ›  技术社区  ›  Mike Lowery

需要帮助修改正则表达式吗

  •  0
  • Mike Lowery  · 技术社区  · 15 年前

    总有一天我会学好正则表达式,但现在。。。

    "<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"
    

    我现在想同时搜索MP3和OGG文件。似乎是一个简单的或修改(.mp3 | |.ogg),但我不太清楚我如何把它放在那里?看到了吗 Trying to parse links in an HTML directory listing using Java regex 更多信息。

    2 回复  |  直到 8 年前
        1
  •  5
  •   polygenelubricants    15 年前

    了解模式

    您具有以下Java字符串文字:

    // Java string literal
    "<A HREF=\"([^\"]+)\"[^>]*>([^<]+?)\\.mp3</A>"
    

    当处理所有转义序列时,此字符串表示的模式如下:

    // the regex pattern
    <A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>
    

    现在让我们打破这个模式:

    _________       _     _        E________
    <A HREF="([^"]+)"[^>]*>([^<]+?)\.mp3</A>
             \_____/       \______/
                1              2
    

    所以这个正则表达式的部分是:

    1. <A HREF="
    2. ([^"]+) ,即除双引号外的所有内容,在第1组中捕获
    3. "
    4. [^>]* >
    5. > 完全匹配
    6. ([^<]+?) < ,尽可能少,在第2组捕获
    7. .mp3</A> 按字面意思匹配 . 用反斜杠转义)

    • 这个 href 属性值由第2部分匹配;它必须用双引号括起来,并且本身不能包含任何转义的双引号。这场比赛被分为第1组。
    • href公司 必须是第一个属性,否则正则表达式将不匹配。
    • 第6部分匹配文件名,捕获到组2中。

    用regex解析HTML是一项棘手的工作,但是考虑到许多假设,上面的regex似乎大部分时间都能完成这项工作。


    修改图案

    Alternation 在regex中是使用竖条完成的。重要的是要了解它的优先级,以及分组是如何有用的。

    • this|that 匹配以下两个字符串之一:
      • "this"
      • "that"
    • this|that thing
      • “这个”
      • "that thing"
    • (this|that) thing
      • "this thing"
      • “那东西”
    • (this|that) (thing|stuff)
      • “这个东西”
      • "this stuff"
      • "that stuff"

    所以允许两者兼而有之 mp3 ogg 扩展,我们可以修改 mp3 在模式中 (mp3|ogg) . 请注意,此组将匹配扩展并将其捕获到组3中。

    因此,最终的模式是:

    <A HREF="([^"]+)"[^>]*>([^<]+)\.(mp3|ogg)</A>
             \_____/       \_____/  \_______/
              1:url      2:filename   3:ext
    

    作为Java字符串文本,这是:

    "<A HREF=\"([^\"]+)\"[^>]*>([^<]+)\\.(mp3|ogg)</A>"
    

    附录

    […] character class [aeiou] 匹配任何一个小写元音。 [^…] 是一个 否定 角色类。 [^aeiou] 任何事

    这个 (…) capturing group

    这个 * + repetition specifiers . 默认情况下,重复是贪婪的(即匹配为 尽可能)。这个 ? 在里面 +? 使其不情愿(即匹配为 尽可能)。

    请注意 ? 也可以作为 optional repetition specifier 在其他情况下。

    这个 . 是一个元字符 matches (almost) any character . 因为我们需要一个文字句点,所以我们通过在前面加上双斜杠来转义它。

    注意,regex模式在默认情况下是区分大小写的。在Java中,您可能需要使用 Pattern.CASE_INSENSITIVE 标志(可嵌入为 (?i) 在模式中)。

        2
  •  4
  •   Thomas L Holaday    15 年前
    Replace 
        \.mp3
    with
        \.((mp3)|(ogg))