正则表达式匹配字符串之前或之后,每组只返回一个匹配

时间:2017-10-04 18:31:43

标签: java regex

我试图从HTML代码中获取某些id。我有一些工作,但其他我需要帮助的东西。以下是视频的一些示例HTML代码:

<video id="movie1" class="show_movie-camera animation_target movieBorder hasAudio movieId_750" src="/path/to/movie" style="position: absolute; z-index: 505; top: 44.5px; left: 484px; display: none;" preload="true" autoplay="true"></video>
<video id="movie2" class="clickInfo movieId_587" src="/path/to/movie" preload="true" autoplay="true"></video>
<video id="movie300" src="/path/to/movie" preload="true" autoplay="true"></video>

要获取电影ID,我使用此正则表达式查找movieId_ [ID]或电影[ID]:

.*?<object|<video.*?movie(\\d+)|movieId_(\\d+)[^>]*>?.*?

这很有效,但它将movieId_ [ID]和movie [ID]都放在匹配中,而不仅仅是一个。我正在寻找的是使用movieId_ [ID]并使用电影[ID]作为后备。这就是我使用的:

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
int fileId = -1;
while(m.find()) {
    fileId = -1;
    if (m.group(2) != null) {
        fileId = new Integer(m.group(2));
    } else if (m.group(1) != null) {
        fileId = new Integer(m.group(1));
    }
}

这将给我1,750,2,587,300而不是我想要的750,578,300。

此外,我希望获得具有hasAudio类的匹配项。这是我尝试过没有成功的事情:

.*?<object|<video.*?hasAudio.*movieId_(\\d+)|movieId_(\\d+).*hasAudio[^>]*>?.*?";

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:2)

对于第一个问题,请查看以下内容......

.*?<object|<video[^>]*((?<=movieId_)\d+|(?<=movie)\d+)

要使其工作,您的Java代码将是

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(content);
int fileId = -1;
while(m.find()) {
    fileId = -1;
    if (m.group(1) != null) {
        fileId = new Integer(m.group(1));
    }
}

正则表达式演示here

第二条件更新

.*?<object|<video[^>]*hasAudio[^>]*((?<=movieId_)\d+|(?<=movie)\d+)

正则表达式演示here

<强>解释

.*?<object                 //Already existing regex
|                          //OR capture the movie ID as below
<video[^>]*hasAudio[^>]*   //Part of full match include all characters except '>'
                           //This makes sure matches do not go beyond the tag
                           //Also makes sure that hasAudio is part of this string
(                          //START: Our Group1 capture as Movie ID 
(?<=movieId_)\d+           //First try getting id out of moviedId_xxx
|                          //OR if first fails
(?<=movie)\d+              //Second try getting id out of moviexxx
)                          //END: Our Group1 capture as Movie ID

注意: .*?<object始终只匹配<object !!!

更新2

<object|<video[^>]*\K(?:hasAudio[^>]*\K(?:(?<=movieId_)\d+|(?<=movie)\d+)|(?:(?<=movieId_)\d+|(?<=movie)\d+)(?=[^>]*hasAudio))

这里我介绍了跟踪hasAudio的条件(如果有的话)。请注意,在此正则表达式中,完全匹配是movieID,没有组。

我们在这里使用的主要功能是\ K标志,它将匹配位置重置为当前。通过从比赛中丢弃所有先前抓住的角色。这有助于我们绕过可变长度的后视。

演示here