簡體   English   中英

Java中的模式和Matcher正則表達式

[英]Pattern and Matcher regex in Java

我在Java中使用模式和匹配器時遇到問題。

我試圖用它從至少包含.SXXEXX的字符串中提取兩個數字。 XX是我要提取的int。 任何正則表達式/ Java專業人士想幫助我嗎?

這是我最好的嘗試,但是會導致運行時異常.. :(

String s = "Some.Cool.Series.S06E01.720p.HDTV.X264-Pewpew";
Pattern p = Pattern.compile("[^.S].S(\\d2)E(\\d+2)\\p{Alpha}");
Matcher m = p.matcher(s);
String season = m.group(0);
String episode = m.group(1);

您的正則表達式有誤,您需要在訪問組之前調用findmatches方法:

String s = "Some.Cool.Series.S06E01.720p.HDTV.X264-Pewpew";
Pattern p = Pattern.compile("\\.S(\\d{2})E(\\d{2})\\.");
Matcher m = p.matcher(s);
if (m.find() {
   String season = m.group(1);
   String episode = m.group(2);
}

首先,盡管您的正則表達式有錯誤,因此無法編譯,但我必須祝賀您的英勇努力。 即使對於看起來無害且直接的案例,也很難從一開始就獲得正則表達式100%。 假設分隔符為點“。”,則可以通過較小的更正對其進行修改,以從字符串中提取所需的信息。 如您的示例中所示,季節和情節均以確切的SXXEXX格式給出。 這是模式的更正版本: "\\\\.S(\\\\d{2})E(\\\\d{2})\\\\."

您可以分別通過調用季節和情節的m.group(1)m.group(2)來訪問捕獲的組。 java.util.regex.Matcher javadoc引用:

捕獲組從左到右從一個索引開始。 組零表示整個模式,因此表達式m.group(0)等效於m.group()。

為了增強教學范式,我寫了一個單例(僅一個實例),該單例是根據p.17上的Effective Java建議進行設計的(Bloch J.,第2版,2008年)。 使用getInstance()方法訪問的類的實例公開了parse()方法,該方法采用一個字符串,其中包含您要提取和解析的系列信息,並將季節和劇集號保存到各自的私有整數字段中。 最后,作為測試,我們嘗試分析各種(虛構)系列中具有挑戰性的情節名稱的數組-包括您自己的示例-看看我們能否獲得季節和情節的數量。 恕我直言,此示例以簡潔的方式說明了您要實現的目標,不僅是其廣泛的版本,而且:

  1. 重復使用編譯模式的有效方法
  2. 與您嘗試匹配的模式相比,限制程度較小(例如,“ S”,“ s”,“季節”,“季節”,“季節”都是可以匹配季節關鍵字的可接受變體)
  3. 如何使用環視和單詞邊界(?<=(?=\\b
  4. 如何使用(?<name>X)語法使用命名的捕獲組(注意:必須使用Java 7或更高版本,有關更多信息,請參閱此較早的問題
  5. 有關如何分別使用PatternMatcher類的有趣案例。 您也可以在Oracle The Java Tutorials:Regular Expressions中這個非常有教育意義的教程中進行瀏覽。
  6. 如何創建和使用單例

//上課開始

public class SeriesInfoMatcher {

    private int season, episode;
    static final String SEASON_EPISODE_PATTERN = "(?<=\\b|_) s(?:eason)? (?<season>\\d+) e(?:pisode)? (?<episode>\\d+) (?=\\b|_)";
    private final Pattern pattern = Pattern.compile(SEASON_EPISODE_PATTERN, Pattern.CASE_INSENSITIVE | Pattern.COMMENTS);
    private Matcher matcher;
    private String seriesInfoString;
    private static SeriesInfoMatcher instance;

    private SeriesInfoMatcher() {
        resetFields();
    }

    public static SeriesInfoMatcher getInstance() {
        return instance == null ? new SeriesInfoMatcher() : instance;
    }

    /**
     * Analyzes a string containing series information and updates the internal fields accordingly
     * @param unparsedSeriesInfo The string containing episode and season numbers to be extracted. Must not be null or empty.
     */
    public void parse (String unparsedSeriesInfo) {
        try {
            if (unparsedSeriesInfo == null || unparsedSeriesInfo.isEmpty()) {
                throw new IllegalArgumentException("String argument must be non-null and non-empty!");
            }
            seriesInfoString = unparsedSeriesInfo;
            initMatcher();
            while (matcher.find()) {
                season = Integer.parseInt ( matcher.group("season") );
                episode = Integer.parseInt( matcher.group("episode"));
            }
        }
        catch (Exception ex) {
            resetFields();
            System.err.printf("Invalid movie info string format. Make sure there is a substring of \"%s\" format.%n%s", "S{NUMBER}E{NUMBER}", ex.getMessage());
        }
    }

    private void initMatcher() {
        if (matcher == null) {
            matcher = pattern.matcher(seriesInfoString);
        }
        else {
            matcher.reset(seriesInfoString);
        }
    }

    private void resetFields() {
        seriesInfoString = "";
        season = -1;
        episode = -1;
    }

    @Override
    public String toString() {
        return seriesInfoString.isEmpty() ? 
            "<no information to display>": 
            String.format("{\"%s\": %d, \"%s\": %d}", "season", season, "episode", episode);
    }

    public static void main(String[] args){
        // Example movie info strings
        String[] episodesFromVariousSeries = {
            "Some.Cool.Series.S06E01.720p.HDTV.X264-Pewpew",
            "Galactic Wars - S01E02 - A dire development",
            "A.dotted.hell.season3episode15.when.enough.is.enough.XVID",
            "The_underscore_menace_-_The_horror_at_the_end!_[2012]_s05e02",
            "s05e01_-_The_underscore_menace_-_Terror_at_the_beginning_[2012]"
        };
        SeriesInfoMatcher seriesMatcher = new SeriesInfoMatcher();
        System.out.printf( "%-80s %-20s%n", "Episode Info", "Parsing Results" );
        for (String episode: episodesFromVariousSeries) {
            seriesMatcher.parse(episode);
            System.out.printf( "%-80s %-20s%n", episode, seriesMatcher );
        }
    }
}

main()的輸出是:

Episode Info                                                                     Parsing Results     
Some.Cool.Series.S06E01.720p.HDTV.X264-Pewpew                                    {"season": 6, "episode": 1}
Galactic Wars - S01E02 - A dire development                                      {"season": 1, "episode": 2}
A.dotted.hell.season3episode15.when.enough.is.enough.XVID                        {"season": 3, "episode": 15}
The_underscore_menace_-_The_horror_at_the_end!_[2012]_s05e02                     {"season": 5, "episode": 2}
s05e01_-_The_underscore_menace_-_Terror_at_the_beginning_[2012]                  {"season": 5, "episode": 1}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM