Java streams修改字符串列表以仅保留每个字符串的子字符串
我试图修改字符串列表,以仅保留每个字符串的子字符串。以下是我想做的:Java streams修改字符串列表以仅保留每个字符串的子字符串,java,regex,string,java-stream,Java,Regex,String,Java Stream,我试图修改字符串列表,以仅保留每个字符串的子字符串。以下是我想做的: List<String> paychecks = new ArrayList<>(); paychecks.add("Paycheck_Box_EMP_61299_451"); paychecks.add("Paycheck_Box_EMP_5512_221"); paychecks.add("Paycheck_Box_EMP_99993_881&quo
List<String> paychecks = new ArrayList<>();
paychecks.add("Paycheck_Box_EMP_61299_451");
paychecks.add("Paycheck_Box_EMP_5512_221");
paychecks.add("Paycheck_Box_EMP_99993_881");
paychecks.add("Paycheck_Box_EMP_831_141");
paychecks.replaceAll(paycheck -> paycheck.subString("insert here"))
更新(第二次尝试):
抛出错误:
java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 26
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
就我个人而言,我不擅长写作,更不擅长阅读正则表达式,因此我不想让替换变得高效,而是优先考虑人类的可读性 除非我考虑修改一组非常大的数据,否则我会执行以下操作:
List<String> paychecks = new ArrayList<>();
paychecks.add("Paycheck_Box_EMP_61299_451");
paychecks.add("Paycheck_Box_EMP_5512_221");
paychecks.add("Paycheck_Box_EMP_99993_881");
paychecks.add("Paycheck_Box_EMP_831_141");
paychecks.replaceAll(person -> person
.replaceFirst("^Paycheck_Box_EMP_", "") // remove prefix
.replaceFirst("_.*$", "")); // remove suffix
System.out.println(paychecks); // [61299, 5512, 99993, 831]
List paychecks=new ArrayList();
工资支票。添加(“工资支票盒”EMP 61299_451);
工资支票。添加(“工资支票盒”EMP_5512_221);
工资支票。添加(“工资支票盒”EMP 993_881);
工资支票。添加(“工资支票盒”EMP_831_141);
工资支票。全部替换(个人->个人
.replaceFirst(“^Paycheck\u Box\u EMP\uuux”,”)//删除前缀
.replaceFirst(“.*$”,“);//删除后缀
System.out.println(工资支票);//[61299, 5512, 99993, 831]
您可以进一步细化前缀和后缀regexp,具体取决于您对格式的了解程度
例如,在更新的问题中,前缀始终是常量,因此可以使用简单的
replace()
调用。同样,如果你知道后缀总是数字的,你可以使用[0-9]*
而不是*
如果我正确理解了任务,你想从工资支票盒中获得
所以你不想替换一些东西,你想要的是提取一些东西,对吗
这应该是这样的:
[61299, 5512, 99993, 831]
List<String> paychecks = new ArrayList<>();
paychecks.add( "Paycheck_Box_EMP_61299_451" );
paychecks.add( "Paycheck_Box_EMP_5512_221" );
paychecks.add( "Paycheck_Box_EMP_99993_881" );
paychecks.add( "Paycheck_Box_EMP_831_141" );
final var pattern = Pattern.compile( "Paycheck_Box_EMP_(\\d{3,5})_\\d{3}" );
paychecks = paychecks.stream()
.map( paycheck -> pattern.matcher( paycheck ) )
.filter( matcher -> matcher.find() )
.map( matcher -> group( 1 ) )
.collect( Collectors.toList() );
修复了基于Alex Rudenko的评论的Java。您可以使用正则表达式,工资支票盒\u EMP(\d+).*
并用组(1)替换字符串
演示:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> paychecks = new ArrayList<>();
paychecks.add("Paycheck_Box_EMP_61299_451");
paychecks.add("Paycheck_Box_EMP_5512_221");
paychecks.add("Paycheck_Box_EMP_99993_881");
paychecks.add("Paycheck_Box_EMP_831_141");
List<String> substrs =
paychecks.stream()
.map(s -> s.replaceAll("Paycheck_Box_EMP_(\\d+).*", "$1"))
.collect(Collectors.toList());
System.out.println(substrs);
}
}
[61299, 5512, 99993, 831]
正则表达式的解释如下:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> paychecks = new ArrayList<>();
paychecks.add("Paycheck_Box_EMP_61299_451");
paychecks.add("Paycheck_Box_EMP_5512_221");
paychecks.add("Paycheck_Box_EMP_99993_881");
paychecks.add("Paycheck_Box_EMP_831_141");
List<String> substrs =
paychecks.stream()
.map(s -> s.replaceAll("Paycheck_Box_EMP_(\\d+).*", "$1"))
.collect(Collectors.toList());
System.out.println(substrs);
}
}
[61299, 5512, 99993, 831]
试着这样做:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> paychecks = new ArrayList<>();
paychecks.add("Paycheck_Box_EMP_61299_451");
paychecks.add("Paycheck_Box_EMP_5512_221");
paychecks.add("Paycheck_Box_EMP_99993_881");
paychecks.add("Paycheck_Box_EMP_831_141");
List<String> substrs =
paychecks.stream()
.map(s -> s.replaceAll("Paycheck_Box_EMP_(\\d+).*", "$1"))
.collect(Collectors.toList());
System.out.println(substrs);
}
}
[61299, 5512, 99993, 831]
- 步骤1:删除目标子字符串e.i的前缀工资支票盒\u EMP\u61299\u 451
然后是临时结果子字符串:61299_451
- 步骤2:删除目标子字符串e.i 61299的后缀_451,子字符串的最终结果将是61299
工资支票。全部替换(x->x)
.replaceFirst(“^Paycheck\u Box\u EMP\uuux”,”)
.replaceFirst(“..*$”,“)
您的第二次尝试几乎是对的,这是最简单的方法:
String prefix = "Paycheck_Box_EMP_"; // or use 17 instead of prefix.length()
paychecks.replaceAll(paycheck ->
paycheck.replaceAll(paycheck, paycheck.substring(prefix.length(), paycheck.lastIndexOf('_'))));
您与使用subString()
的关系如何?仅仅使用replaceAll()
和一个regexp模式可能会更干净。我不是太已婚哈哈,但是什么是regex模式来忽略两件事之间的一切呢?事实上,我发现将其分为两个调用更具可读性,一个用于修剪前端,另一个用于修剪后端,例如people.replaceAll(person->person.replaceAll(“^.*EMP_u“,”).replaceAll(“.*$”,”)
哦,你基本上是在EMP之前和第二次EMP之后删除所有内容吗?太好了,非常感谢你了,我现在就知道了,或者在一次替换操作中,paychecks.replaceAll(p->p.replaceFirst(“^Paycheck\u Box\u EMP(\\d+).*,“$1”))
您还可以考虑匹配前缀在这里是否很重要,并决定只提取第一个数字:paychecks.replaceAll(p->p.replaceFirst(“.*”(\\d+).*”,“$1”);
这不起作用,线程“main”中的异常java.lang.IllegalStateException:未找到匹配项
。您应该通过flatMap
:paychecks=paychecks.stream().flatMap(paycheck->pattern.matcher(paycheck).results().map(mr->mr.group(1)).Collector(Collectors.toList())
问题在于Java代码,而不是regexp,我想,Matcher::find
或Matcher::matches
必须在调用Matcher::group
之前被调用!这里的常见错误是……重用一个准备好的模式是一个很好的优化,不过,它的使用不必那么复杂ted.paychecks.replaceAll(paycheck->pattern.matcher(paycheck.replaceFirst($1));
将提取第一组。