gpt4 book ai didi

java - 检查替换字符串是否有效

转载 作者:行者123 更新时间:2023-11-30 10:39:58 25 4
gpt4 key购买 nike

这是我的实用方法,用于检查 replacement string 是否为有效:

public static boolean isValidReplacementString(String regex, String replacement) {
try {
"".replaceFirst(regex, replacement);
return true;
} catch (IllegalArgumentException | NullPointerException e) {
return false;
}
}

我想在执行真正的替换之前检查这一点,因为获取源字符串是昂贵的 (I/O)。

我发现这个解决方案很老套。标准库中是否已经有我缺少的方法?


编辑: As pointed out by sln , 如果找不到匹配项,这甚至不起作用。


编辑: Following shmosel's answer ,我想出了这个“解决方案”:

private static boolean isLower(char c) {
return c >= 'a' && c <= 'z';
}

private static boolean isUpper(char c) {
return c >= 'A' && c <= 'Z';
}

private static boolean isDigit(char c) {
return isDigit(c - '0');
}

private static boolean isDigit(int c) {
return c >= 0 && c <= 9;
}

@SuppressWarnings("unchecked")
public static void checkRegexAndReplacement(String regex, String replacement) {
Pattern parentPattern = Pattern.compile(regex);
Map<String, Integer> namedGroups;
int capturingGroupCount;

try {
Field namedGroupsField = Pattern.class.getDeclaredField("namedGroups");
namedGroupsField.setAccessible(true);
namedGroups = (Map<String, Integer>) namedGroupsField.get(parentPattern);
Field capturingGroupCountField = Pattern.class.getDeclaredField("capturingGroupCount");
capturingGroupCountField.setAccessible(true);
capturingGroupCount = capturingGroupCountField.getInt(parentPattern);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("That's what you get for using reflection!", e);
}

int groupCount = capturingGroupCount - 1;

// Process substitution string to replace group references with groups
int cursor = 0;

while (cursor < replacement.length()) {
char nextChar = replacement.charAt(cursor);
if (nextChar == '\\') {
cursor++;
if (cursor == replacement.length())
throw new IllegalArgumentException(
"character to be escaped is missing");
nextChar = replacement.charAt(cursor);
cursor++;
} else if (nextChar == '$') {
// Skip past $
cursor++;
// Throw IAE if this "$" is the last character in replacement
if (cursor == replacement.length())
throw new IllegalArgumentException(
"Illegal group reference: group index is missing");
nextChar = replacement.charAt(cursor);
int refNum = -1;
if (nextChar == '{') {
cursor++;
StringBuilder gsb = new StringBuilder();
while (cursor < replacement.length()) {
nextChar = replacement.charAt(cursor);
if (isLower(nextChar) ||
isUpper(nextChar) ||
isDigit(nextChar)) {
gsb.append(nextChar);
cursor++;
} else {
break;
}
}
if (gsb.length() == 0)
throw new IllegalArgumentException(
"named capturing group has 0 length name");
if (nextChar != '}')
throw new IllegalArgumentException(
"named capturing group is missing trailing '}'");
String gname = gsb.toString();
if (isDigit(gname.charAt(0)))
throw new IllegalArgumentException(
"capturing group name {" + gname +
"} starts with digit character");
if (namedGroups == null || !namedGroups.containsKey(gname))
throw new IllegalArgumentException(
"No group with name {" + gname + "}");
refNum = namedGroups.get(gname);
cursor++;
} else {
// The first number is always a group
refNum = (int)nextChar - '0';
if (!isDigit(refNum))
throw new IllegalArgumentException(
"Illegal group reference");
cursor++;
// Capture the largest legal group string
boolean done = false;
while (!done) {
if (cursor >= replacement.length()) {
break;
}
int nextDigit = replacement.charAt(cursor) - '0';
if (!isDigit(nextDigit)) { // not a number
break;
}
int newRefNum = (refNum * 10) + nextDigit;
if (groupCount < newRefNum) {
done = true;
} else {
refNum = newRefNum;
cursor++;
}
}
}
if (refNum < 0 || refNum > groupCount) {
throw new IndexOutOfBoundsException("No group " + refNum);
}
} else {
cursor++;
}
}
}

如果此方法抛出异常,则正则表达式或替换字符串无效。

这甚至比 replaceAllreplaceFirst 更严格,因为如果没有找到匹配项,这些方法将不会调用 appendReplacement,因此“缺失”无效的组引用。

最佳答案

我会说你最好的选择是复制在 Matcher.appendReplacement() 中实现的过程,删除与源字符串或结果字符串有关的任何逻辑。这不可避免地意味着您将无法进行某些验证,例如验证组名称和索引,但您应该能够应用其中的大部分。

关于java - 检查替换字符串是否有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39089652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com