获取字符出现 "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));
我有一个 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));