String (@NotNull String glob, boolean acceptChildren) { glob = glob.trim(); String cached = GLOBS_CACHE.get(glob); if (cached != null) { return cached; } StringBuilder sb = new StringBuilder("^"); boolean escape = false, star = false, doubleStar = false, bracket = false; int beginIndex = 0; if (StringUtil.startsWith(glob, IgnoreFileConstants.DOUBLESTAR)) { sb.append("(?:[^/]*?/)*"); beginIndex = 2; doubleStar = true; } else if (StringUtil.startsWith(glob, "*/")) { sb.append("[^/]*"); beginIndex = 1; star = true; } else if (StringUtil.equals(IgnoreFileConstants.STAR, glob)) { sb.append(".*"); } else if (StringUtil.startsWithChar(glob, '*')) { sb.append(".*?"); } else if (StringUtil.startsWithChar(glob, '/')) { beginIndex = 1; } else { int slashes = StringUtil.countChars(glob, '/'); if (slashes == 0 || (slashes == 1 && StringUtil.endsWithChar(glob, '/'))) { sb.append("(?:[^/]*?/)*"); } } char[] chars = glob.substring(beginIndex).toCharArray(); for (char ch : chars) { if (bracket && ch != ']') { sb.append(ch); continue; } else if (doubleStar) { doubleStar = false; if (ch == '/') { sb.append("(?:[^/]*/)*?"); continue; } else { sb.append("[^/]*?"); } } if (ch == '*') { if (escape) { sb.append("\\*"); escape = false; star = false; } else if (star) { char prev = sb.length() > 0 ? sb.charAt(sb.length() - 1) : '\0'; if (prev == '\0' || prev == '^' || prev == '/') { doubleStar = true; } else { sb.append("[^/]*?"); } star = false; } else { star = true; } continue; } else if (star) { sb.append("[^/]*?"); star = false; } switch (ch) { case '\\' -> { if (escape) { sb.append("\\\\"); escape = false; } else { escape = true; } } case '?' -> { if (escape) { sb.append("\\?"); escape = false; } else { sb.append('.'); } } case '[' -> { if (escape) { sb.append('\\'); escape = false; } else { bracket = true; } sb.append(ch); } case ']' -> { if (!bracket) { sb.append('\\'); } sb.append(ch); bracket = false; escape = false; } case '.', '(', ')', '+', '|', '^', '$', '@', '%' -> { sb.append('\\'); sb.append(ch); escape = false; } default -> { escape = false; sb.append(ch); } } } if (star || doubleStar) { if (StringUtil.endsWithChar(sb, '/')) { sb.append(acceptChildren ? ".+" : "[^/]+/?"); } else { sb.append("[^/]*/?"); } } else { if (StringUtil.endsWithChar(sb, '/')) { if (acceptChildren) { sb.append("[^/]*"); } } else { sb.append(acceptChildren ? "(?:/.*)?" : "/?"); } } sb.append('$'); GLOBS_CACHE.put(glob, sb.toString()); return sb.toString(); }