繁体   English   中英

正则表达式替换两组

[英]regular expression replace two group

我有这样的模式: <[a-zA-Z][^>]*(?:poster|src)=(['\\"])([^'\\"]+)\\\\1[^>]*>在这里,我想替换src或poster属性的值。

这是对的

<video src='srcVal' />

<video poster='posterVal' src='srcVal' />

但对于

<video poster='posterVal' src='srcVal' />

由于matcher.group(2)仅返回srcVal ,因此仅更改src值。

public class Test {
    public static void main(String[] args) throws Exception {
        String html = "<video poster='posterVal' src='srcVal' />";
        Pattern resourcePattern = Pattern.compile("<[a-zA-Z][^>]*(?:poster|src)=(['\"])([^'\"]+)\\1[^>]*>");
        Matcher matcher = resourcePattern.matcher(html);
        int last = 0;
        StringBuilder sb = new StringBuilder();
        while(matcher.find()) {
            String path = matcher.group(2) + "Changed";
            sb.append( html.substring(last, matcher.start(2)) + path );
            last = matcher.end(2);
        }
        sb.append(html.substring(last));
        System.out.println(sb);
        //outputs <video poster='posterVal' src='srcValChanged' />
        //expecting <video poster='posterValChanged' src='srcValChanged' />
    }
}

有没有人知道如何做到这一点?

基本问题是表达式开头附近的[^>]* 因为*是贪婪的,这会吃掉尽可能多的字符,同时仍然允许表达式的其余部分匹配,因此给定

<video poster='posterVal' src='srcVal' />

[^>]*将使ideo poster='posterVal'吞噬直至src=之前的空格。

我会采取不同的方法,而不是尝试编写与整个标签匹配的正则表达式,而只是编写与您感兴趣的属性匹配的正则表达式,然后替换该表达式的所有匹配项

html.replaceAll("\\b((?:poster|src)=)(['\"])([^'\"]+)\\1", "$1$2$3Changed$2")

但是,正如其他张贴者所评论的那样,使用一种能够理解该语言的适当解析器,而不是尝试使用正则表达式来操纵文本表示,会更加明智。

我不会使用正则表达式来执行此操作,但是您可以尝试以下操作:

<[a-zA-Z]*[^>]*(?:(poster)|src)=(['\"])([^'\"]+)\\2(?(1)[^>]*(?:src=(['\"])([^'\"]+)\\4)?[^>]*|[^>]*(?:poster=(['\"])([^'\"]+)\\6)?[^>]*)>

尽管到目前为止我还没有时间进行测试,对不起。

编辑:
不太注重性能:

<[a-zA-Z]*(?=(?:[^>]*?poster=['\"]([^'\"]+))?)(?=(?:[^>]*?src=['\"]([^'\"]+))?)[^>]*(?:poster|src)[^>]*>

如果您只想匹配视频标签,请将其更改为(这将大大改善它):

<video(?=(?:[^>]*?poster=['\"]([^'\"]+))?)(?=(?:[^>]*?src=['\"]([^'\"]+))?)[^>]*(?:poster|src)[^>]*>

说明:(因为我想它看起来一定很令人不安)

我们正在使用2个前瞻记录来捕获有趣的内容。 先行者将使我们能够检查两次即将发生的事情,因此忽略了顺序。 但是,这些前瞻必须始终有效(使用*和?来确保这一点),但仍要保持贪婪,同时要保持懒惰(是什么?):看到海报/ src后,我们必须立即停止,但要走得足够远抓住那些。 .*?a? 永远一无所获。 所以我们在这里使用(?:.*?a)? 这里的行为是尝试以懒惰的方式捕获a ,而如果失败则不成问题。
正则表达式的最后一部分是确保我们仅捕获带有发帖人或src属性的标签,因为我们的先行者只会捕获该对象,并且肯定不能用来捕获它。

请注意,我删除了对您的属性的检查,因为无论如何它都没有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM