我在Java中使用Pattern和Matcher时遇到了问题..
我试图用它从至少包含.SXXEXX的字符串中提取两个数字。其中XX是我要提取的int。任何正则表达式/ java pro都想帮帮我吗?
这是我最好的尝试,但它会导致运行时异常.. :(
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);
答案 0 :(得分:1)
您的正则表达式错误,您需要在访问群组之前调用find
或matches
方法:
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);
}
答案 1 :(得分:1)
首先,尽管你的正则表达式有错误,因此无法编译,我必须祝贺你勇敢的努力。即使对于看起来无害且直截了当的案例,也很难从一开始就100%正确使用正则表达式。通过较小的更正,您可以修改它以从字符串中提取所需的信息,假设分隔符是点'。如在您的示例中,季节和剧集以精确的SXXEXX
格式给出。以下是该模式的更正版本:"\\.S(\\d{2})E(\\d{2})\\."
您可以分别为季节和剧集调用m.group(1)
和m.group(2)
来访问捕获的群组。引用java.util.regex.Matcher
javadoc :
捕获组从左到右编制索引,从1开始。组零表示整个模式,因此表达式m.group(0)等同于m.group()。
为了增强教学范式,我编写了一个单例(只有一个实例),它是根据第17页的 Effective Java 建议设计的(Bloch J.,第2版,2008年)。使用getInstance()
方法访问的类的实例公开了parse()
方法,该方法接受包含您要提取并解析它的系列信息的字符串,将季节和剧集编号保存到各自的私有整数字段。最后作为测试,我们尝试从各种(虚构)系列中解析一系列挑战性剧集名称 - 包括您自己的例子 - 并看看我们是否可以获得季节和剧集的数量。恕我直言这个例子简明扼要地说明了你想要实现的更广泛的版本,还有:
(?<=
以及(?=
和\b
(?<name>X)
语法使用命名捕获组(请注意:必须使用Java 7或更高版本,有关详细信息,请参阅this older question)Pattern
和Matcher
类的有趣案例。您还可以从 Oracle The Java Tutorials: Regular Expressions //课程开始
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}