获取字符出现 "first two" 次之间的子字符串

Get substring between "first two" occurrences of a character

我有一个 String:

 String thestra = "/aaa/bbb/ccc/ddd/eee";

每次,在我的情况下,对于这个 Sting,至少会出现两个斜杠。

我得到如下所示的 /aaa/,它是字符串中字符 / 的“前两次出现”之间的子字符串。

 System.out.println("/" + thestra.split("\/")[1] + "/");

它解决了我的目的,但我想知道是否有其他更优雅、更干净的替代方案?

请注意,我需要在 aaa 周围加上斜线(开头和结尾)。即 /aaa/

您可以使用 indexOf,它接受索引的第二个参数以开始搜索:

int start = thestra.indexOf("/");
int end = thestra.indexOf("/", start + 1) + 1;
System.out.println(thestra.substring(start, end));

它是否更优雅是一个见仁见智的问题,但至少它没有找到字符串中的每个 / 或创建一个不必要的数组。

Pattern.compile("/.*?/")
            .matcher(thestra)
            .results()
            .map(MatchResult::group)
            .findFirst().ifPresent(System.out::println);

您可以测试这个变体:)

最诚挚的问候,Fr0z3Nn

使用 java.util.regex 中的模式和匹配器。

Pattern pattern = Pattern.compile("/.*?/");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) { 
    String match = matcher.group(0);  // output
}

Scanner::findInLine 可以使用返回模式的第一个匹配项:

String thestra = "/aaa/bbb/ccc/ddd/eee";
System.out.println(new Scanner(thestra).findInLine("/[^/]*/"));

输出:

/aaa/

其中一种方法是用 regex[^/]*(/[^/].*?/).* 的第 1 组替换字符串,如下所示:

public class Main {
    public static void main(String[] args) {
        String thestra = "/aaa/bbb/ccc/ddd/eee";
        String result = thestra.replaceAll("[^/]*(/[^/].*?/).*", "");
        System.out.println(result);
    }
}

输出:

/aaa/

正则表达式的解释:

  • [^/]* : 不是字符, /, 任意次数
  • ( : 第 1 组开始
    • / : 字符,/
    • [^/]:不是字符,/
    • .*?: 任何字符任意次数(惰性匹配)
    • / : 字符,/
  • ):组#1 结束
  • .* : 任意字符任意次数

根据 Holger 的以下宝贵建议更新了答案:

注意对于Java正则引擎来说,/没有特殊意义,这里不需要转义。此外,由于您只期望一个匹配项(末尾的 .* 可确保这一点),因此 replaceFirst 会更加地道。由于没有关于第一个 / 始终位于字符串开头的声明,因此在模式前面加上 .*?[^/]* 是个好主意。

Every time, in my situation, for this Sting, minimum two slashes will be present

如果可以保证,在每个 / 处拆分,保留这些分隔符并取前三个子字符串。

String str = String.format("%s%s%s",(thestra.split("((?<=\/)|(?=\/))")));

您还可以匹配开头的正斜杠,然后使用 negated character class [^/]* 来选择匹配 / 以外的任何字符,然后匹配结尾的正斜杠。

String thestra = "/aaa/bbb/ccc/ddd/eee";
Pattern pattern = Pattern.compile("/[^/]*/");
Matcher matcher = pattern.matcher(thestra);

if (matcher.find()) {
    System.out.println(matcher.group());
}

输出

/aaa/

我很惊讶,从 Java 7 开始,没有人提到使用 Path

String thestra = "/aaa/bbb/ccc/ddd/eee";
String path = Paths.get(thestra).getName(0).toString();
System.out.println("/" + path + "/");
/aaa/
String thestra = "/aaa/bbb/ccc/ddd/eee";
System.out.println(thestra.substring(0, thestra.indexOf("/", 2) + 1));