我进入这种情况是为了编写一个通用函数,该函数只能从字符串中提取第一次出现的字符和所有数字。
输入字符串(说):ABC123-45DEF-GH67IJ9输出字符串:A123-45D-G679
我已经确定了一种方法,但是程序的复杂度很高。这里有两种对我不利的情况:
这是我的代码段:
package Test;
import java.util.LinkedList;
public class FirstLetterAndNumerics {
static void firstLetterAndNumber(String string) {
StringBuffer sb = new StringBuffer();
LinkedList<String> ll = new LinkedList<String>();
String[] str = string.split("-");
boolean flag = true;
for (int i = 0; i < str.length; i++) {
ll.add(str[i]);
}
for (int j = 0; j < ll.size(); j++) {
if (Character.isAlphabetic(ll.get(j).charAt(0))) {
if (flag == false) {
sb.append("-");
}
sb.append(ll.get(j).charAt(0));
for (int k = 1; k < ll.get(j).length(); k++) {
if (Character.isAlphabetic(ll.get(j).charAt(k))) {
flag = false;
} else if (Character.isDigit(ll.get(j).charAt(k))) {
sb.append(ll.get(j).charAt(k));
}
}
sb.append("-");
flag = true;
} else if (Character.isDigit(ll.get(j).charAt(0))) {
sb.append(ll.get(j).charAt(0));
for (int l = 1; l < ll.get(j).length(); l++) {
if (Character.isDigit(ll.get(j).charAt(l))) {
sb.append(ll.get(j).charAt(l));
} else if (Character.isAlphabetic(ll.get(j).charAt(l)) && flag == true) {
sb.append(ll.get(j).charAt(l));
flag = false;
}
}
}
}
System.out.println(sb);
}
public static void main(String[] args) {
firstLetterAndNumber("ABC123-45DEF-GH67IJ9");
}
}
您可以将此(\d*)([A-Za-z]{1})[A-Z]*(\d*)[A-Z]*(\d*)
正则表达式用于更简单的方法。它会捕获组中的正确部分,因此您需要连接组。
Here是正则表达式的工作方式。
此代码段附加了匹配项。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatching {
public static void main(String a[])
{
String testStr="ABC123-45DEF-GH67IJ9";
String regEx = "(\\d*)([A-Za-z]{1})[A-Z]*(\\d*)[A-Z]*(\\d*)";
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(testStr);
StringBuilder outStr = new StringBuilder();
while (matcher.find()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
outStr.append(matcher.group(i));
}
outStr.append("-");
}
outStr.deleteCharAt( outStr.length() - 1 ); // delete the extra "-"
System.out.println(outStr.toString());
}
}
打印:
A123-45D-G679
最后,我不确定您想要的内容是否可以在单个组中捕获。这是我找到的解决方案。
您正在以连字符开头分割字符串。要确保该字符串包含大写字符char和digit,并用连字符分隔,可以首先使用:
if(string.matches("[A-Z0-9]+(?:-[A-Z0-9]+)+")) {
然后您可以使用2个捕获组并利用\G
模式。
(?:(\b[0-9]*[A-Z])|\G(?!^))[A-Z]*([0-9]*)
将匹配
(?:
非捕获组(
捕获组1\b[0-9]*[A-Z]
单词边界,匹配0+个数字和单个字符A-Z)
关闭组1|
或\G(?!^)
在上一场比赛的末尾,而不是在开始时断言位置)
关闭非捕获组[A-Z]*
匹配0 +字符A-Z([0-9]*)
捕获组2,匹配0+个数字在替换中,使用2个捕获组$1$2
例如
static void firstLetterAndNumber(String string) {
if(string.matches("[A-Z0-9]+(?:-[A-Z0-9]+)+")) {
Pattern pattern = Pattern.compile("(?:(\\b\\d*[A-Z])|\\G(?!^))[A-Z]*(\\d*)");
Matcher matcher = pattern.matcher(string);
System.out.println(matcher.replaceAll("$1$2");
}
}
正在运行firstLetterAndNumber("ABC123-45DEF-GH67IJ9");
将输出
A123-45D-G679