在 java 中将正则表达式模式替换为小写

Replace regex pattern to lowercase in java

我正在尝试将 url 字符串替换为小写字母,但希望保持特定模式字符串不变。

例如:输入如:

http://BLABLABLA?qUERY=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}

预期的输出会小写url但多个宏是原始的:

http://blablabla?query=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}

我试图使用正则表达式捕获字符串,但没有找到进行替换的正确方法。此外,似乎使用 replaceAll() 并不能完成这项工作。有什么提示吗?

这个正则表达式将匹配第一个 &macro 之前的所有字符,并将 http:// 和第一个 &macro 之间的所有字符放在自己的组中,以便您可以修改它。

http://(.*?)&macro

Tested here

更新:如果您不想使用组,此正则表达式将仅匹配 http:// 和第一个 &macro

之间的字符
(?<=http://)(.*?)(?=&macro)

Tested here

您似乎想将任何不在 ${...} 内的大写字符更改为小写形式。

有结构

Matcher matcher = ...

StringBuffer buffer = new StringBuffer();
while (matcher.find()){
    String matchedPart = ...
    ...
    matcher.appendReplacement(buffer, replacement); 
}
matcher.appendTail(buffer);
String result = buffer.toString();

或者从 Java 9 开始我们可以使用 Matcher#replaceAll​(Function<MatchResult,String> replacer) 并重写为

String replaced = matcher.replaceAll(m -> {
    String matchedPart = m.group();
    ...
    return replacement;
});

您可以根据matchedPart动态构建replacement

所以你可以让你的正则表达式先尝试匹配 ${...} 然后再匹配(当 ${..} 不会被匹配,因为正则表达式光标不会放在它前面)让它匹配 [A-Z].在迭代匹配时,您可以根据匹配结果(例如它的长度或它是否以 $ 开头)来决定是否要使用它的小写形式或原始形式作为替换。

BTW 正则表达式引擎允许我们在 replacement 部分放置 $x(其中 x 是组 ID)或 ${name}(其中 name 被命名为group) 这样我们就可以重用匹配的那些部分。但是如果我们想将 ${..} 作为文字替换,我们需要转义 $。为了不手动执行,我们可以使用 Matcher.quoteReplacement.

演示:

String yourUrlString = "http://BLABLABLA?qUERY=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}";

Pattern p = Pattern.compile("\$\{[^}]+\}|[A-Z]");
Matcher m = p.matcher(yourUrlString);

StringBuffer sb = new StringBuffer();
while(m.find()){
    String match = m.group();
    if (match.length() == 1){
        m.appendReplacement(sb, match.toLowerCase());
    } else {
        m.appendReplacement(sb, Matcher.quoteReplacement(match));
    }
}
m.appendTail(sb);
String replaced = sb.toString();
System.out.println(replaced);

或在Java9

String replaced = Pattern.compile("\$\{[^}]+\}|[A-Z]")
        .matcher(yourUrlString)
        .replaceAll(m -> {
            String match = m.group();
            if (match.length() == 1)
                return match.toLowerCase();
            else
                return Matcher.quoteReplacement(match); 
        });
System.out.println(replaced);

输出:http://blablabla?query=sth&macro1=${MACRO_STR1}&macro2=${macro_str2}