实现支持通配符*的字符串匹配检测(禁用indexOf方法)
带通配符*的字符串包含检测实现
需要实现类似String.contains()的字符串包含检测功能,额外支持通配符*匹配规则:
- 通配符
*可出现零次、一次或多次,每次匹配零个或多个任意字符 - 若
*前带有\字符,则该*视为普通字符,需匹配文本中的*
匹配示例
"abc" <- "" 结果: true "abcd" <- "a*d" 结果: true "a*cd" <- "a\\*cd" 结果: true "abc" <- "A" 结果: false "" <- "*" 结果: true "abcd" <- "**a**b****c***d***" 结果: true "\\" <- "\\" 结果: true "***" <- "*\\**\\*\\*" 结果: true "abcd*abcde" <- "a*\\*abcd" 结果: true
现有代码问题
我找到一段Java代码,已添加空值与空串校验,普通字符串匹配场景可用,但无法处理通配符相关逻辑:
public static void stringMatch(String text, String pattern) { int len_t = text.length(); int len_p = pattern.length(); int k = 0, i = 0, j = 0; // 查找匹配模式的位置 for (i = 0; i <= (len_t - len_p); i++) { for (j = 0; j < len_p; j++) { if (text.charAt(i + j) != pattern.charAt(j)) break; } if (j == len_p) { k++; System.out.println("Pattern Found at Position: " + i); } } if (k == 0) System.out.println("No Match Found!"); else System.out.println("Total Instances Found = " + k); }
修正后的实现
下面是支持通配符和转义字符的字符串包含检测代码:
public static boolean containsWithWildcard(String text, String pattern) { // 空值校验 if (text == null || pattern == null) { return false; } // 空模式匹配任何文本 if (pattern.isEmpty()) { return true; } int textIdx = 0; int patternIdx = 0; int textLen = text.length(); int patternLen = pattern.length(); int lastTextPos = -1; int lastPatternPos = -1; while (textIdx < textLen) { boolean isEscapedStar = patternIdx > 0 && pattern.charAt(patternIdx - 1) == '\\' && pattern.charAt(patternIdx) == '*'; // 普通字符匹配(包括未转义的*) if (patternIdx < patternLen && !isEscapedStar && (text.charAt(textIdx) == pattern.charAt(patternIdx) || pattern.charAt(patternIdx) == '*')) { if (pattern.charAt(patternIdx) == '*') { // 记录回溯点,处理通配符匹配 lastTextPos = textIdx; lastPatternPos = patternIdx; patternIdx++; } else { // 普通字符匹配,双指针前进 textIdx++; patternIdx++; } } else if (patternIdx < patternLen && patternIdx + 1 < patternLen && pattern.charAt(patternIdx) == '\\' && pattern.charAt(patternIdx + 1) == '*') { // 处理转义的*,需要匹配文本中的* if (text.charAt(textIdx) == '*') { textIdx++; patternIdx += 2; } else { // 不匹配则回溯 if (lastTextPos == -1) { return false; } textIdx = lastTextPos + 1; patternIdx = lastPatternPos; } } else { // 当前字符不匹配,尝试回溯到最近的*位置 if (lastTextPos == -1) { return false; } textIdx = lastTextPos + 1; patternIdx = lastPatternPos; } } // 处理模式末尾剩余的通配符* while (patternIdx < patternLen) { if (pattern.charAt(patternIdx) == '*' && (patternIdx == 0 || pattern.charAt(patternIdx - 1) != '\\')) { patternIdx++; } else if (patternIdx + 1 < patternLen && pattern.charAt(patternIdx) == '\\' && pattern.charAt(patternIdx + 1) == '*') { // 剩余未匹配的转义*,无对应文本字符 return false; } else { // 剩余普通字符未匹配 return false; } } return true; } // 测试用例验证 public static void main(String[] args) { System.out.println(containsWithWildcard("abc", "")); // true System.out.println(containsWithWildcard("abcd", "a*d")); // true System.out.println(containsWithWildcard("a*cd", "a\\*cd")); // true System.out.println(containsWithWildcard("abc", "A")); // false System.out.println(containsWithWildcard("", "*")); // true System.out.println(containsWithWildcard("abcd", "**a**b****c***d***")); // true System.out.println(containsWithWildcard("\\", "\\")); // true System.out.println(containsWithWildcard("***", "*\\**\\*\\*")); // true System.out.println(containsWithWildcard("abcd*abcde", "a*\\*abcd")); // true }
代码逻辑说明
- 空值与边界处理:优先校验空输入,空模式直接返回匹配成功
- 转义字符识别:将
\*视为普通*字符,需与文本中的*严格匹配 - 通配符回溯机制:遇到
*时记录当前位置,后续匹配失败时回溯,尝试匹配更多文本字符 - 末尾通配符处理:模式末尾的连续
*不影响匹配结果,但若剩余未转义的普通字符则匹配失败
内容的提问来源于stack exchange,提问作者JustDave
相关产品推荐
相关产品推荐

