我有一个用例,我必须解码URI的queryParameter并执行操作(超出此问题的范围)。
假设我有一个URI,我必须解码它。现在我知道目前所有 %20 都会转换为 空间 ,同时创建URI space 应由 %20 表示,但可能会出现我可能会使用 % 为 空间 。因此,我想将 % 转换为 空间 ,以保持向后兼容性。最后有一个注释有助于理解这个问题。
我使用replaceall() %
尝试了%20
,但%20
再次成为%2020
,还有许多其他例外。
这是阅读UPI URI所必需的,根据NPCI的官方文件:
注意:考虑到当前的PSP应用程序开发为“%” 作为空格(“”),银行PSP应支持“%”和“%20”,直到 生态系统与修订一致的时间。因此,落后 应确保兼容性。
编辑1 基于pshemo评论 -
我试过了
str.replaceAll("%(?![0-9a-fA-F])","%20")
不满足上述正则表达式的情况是 “upi:// pay?pa = praksh%40kmbl& pn = Prakash%Abmar& cu = INR”
输出是pn - >普拉卡什“其他人物”mar
答案 0 :(得分:1)
可能不是您想要的答案,但这可能会有所帮助:
public class Test {
public static void main(String... a) {
try {
//
String u = "upi://pay?pa=praksh%40kmbl&pn=Prakash%Abmar&cu=INR";
System.out.println(decode(u));
} catch (Exception e) {
e.printStackTrace();
}
}
private static String decode(String in) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char c = in.charAt(i);
if (c == '%') {
int decoded = Integer.parseInt(in.substring(i + 1, i + 3), 16);
if (decoded >= 32 && decoded <= 126) { //Possible valid char
sb.append((char) decoded);
i += 2;
} else { //not a valid char... maybe a space
sb.append(" ");
}
} else if (c == '+') {
sb.append(" ");
} else {
sb.append(c);
}
}
return sb.toString();
}
}
有很多可能性,因此可能您需要一个“定制”解决方案。上面的代码涵盖了某些情况。
答案 1 :(得分:1)
有趣的问题。如您所见,您不能将%
可靠地替换为一个空格。您需要有关将通过uri传输的内容的其他信息,然后缩小到必须替换的内容,而不是必须替换的内容,例如
%ZTest -> a space for sure
%Abababtest -> is it a space? probably... but we need to be sure that no strange characters or sequences are allowed
%23th%Affleck%20Street -> space? hex? what is what?
您需要更多信息来可靠地解决该问题,例如:
%
作为空格? (因此您可以仅对其进行转换)%20
,那么我们可以假设没有%
会是空格吗?还是两者都可能在URI中显示为空格?有了这些附加信息,应该更容易解决问题。
尽管如此,这还是一种解决方案,可以使您朝正确的方向前进(但请考虑底部的警告!):
Pattern HEX_PATTERN = Pattern.compile("(?i)%([A-F0-9]{2})?");
String CHARSET = "utf-8";
String ENCODED_SPACE = "%20";
String ALLOWED_SYMBOLS = "\\p{L}|\\s|@";
String semiDecode(String uri) throws UnsupportedEncodingException {
Matcher m = HEX_PATTERN.matcher(uri);
StringBuffer semiDecoded = new StringBuffer();
while (m.find()) {
String match = m.group();
String hexString = m.group(1);
String replacementString = match;
if (hexString == null) {
replacementString = ENCODED_SPACE;
} else {
// alternatively to the following just check whether the hex value is in an allowed range...
// you may want to lookup https://en.wikipedia.org/wiki/List_of_Unicode_characters for this
String decodedSymbol = URLDecoder.decode(match, CHARSET);
if (!decodedSymbol.matches(ALLOWED_SYMBOLS)) {
replacementString = ENCODED_SPACE + hexString;
}
}
m.appendReplacement(semiDecoded, replacementString);
}
m.appendTail(semiDecoded);
return semiDecoded.toString();
}
样品用量:
String uri = "upi://pay?pa=praksh%40kmbl&pn=Prakash%Abmar&cu=INR";
String semiDecoded = semiDecode(uri);
System.out.println("Input: " + uri);
System.out.println("Semi-decoded: " + semiDecoded);
System.out.println("Completely decoded query: " + new URI(semiDecoded).getQuery());
将打印:
Input: upi://pay?pa=praksh%40kmbl&pn=Prakash%Abmar&cu=INR
Semi-decoded: upi://pay?pa=praksh%40kmbl&pn=Prakash%20Abmar&cu=INR
Completely decoded query: pa=praksh@kmbl&pn=Prakash Abmar&cu=INR
警告...请记住以下几点:
%##%##
或%##%##%##
将不再被解码)ALLOWED_SYMBOLS
的正则表达式;现在它可以接受任何字母,任何空格和@
)答案 2 :(得分:0)
我为此使用的解决方案是不使用QR中提供的收款人名称,并使用vpa查询PSP以获取正确的名称。这样,您还可以确保收款人存在。
例如:
upi://pay?pa=someone@upi&pn=firstname%lastname&cu=INR
someone@upi
的pa并使用它从PSP获取用户名%
或%20
,
只需使用其他答案中提供的任何解决方法或使用
笔记的更简单解决方案,因为笔记通常不那么重要。