查找字符串中最后一个非数字字符的索引



假设我有一个由数字、字母和符号组成的字符串,

String foo = "987abc<*(123";

我如何能够在字符串foo中的最后一个数字集中找到第一个数字的索引("1",在索引6处(?如果是foo = "123",我将再次获得第一个数字("1",在索引0处(的索引。(如果foo = "",也让它返回索引0(

我对RegEx es和类似的搜索模式非常缺乏经验,而且我尝试的每一种方法都没有正常工作(大多数情况下会导致StringIndexOutOfBoundsException(。

找到字符串中最后一组数字开头的索引的可靠、简单的方法是什么

试试这个。

static int indexOfLastNumber(String s) {
int removedLength = s.replaceFirst("\d+\D*$", "").length();
return s.length() == removedLength ? 0 : removedLength;
}
static void test(String s) {
System.out.println(s + " : " + indexOfLastNumber(s));
}
public static void main(String[] args) {
test("987abc<*(123");
test("987abc<*(123)");
test("123");
test("foo");
test("");
}

输出:

987abc<*(123 : 9
987abc<*(123) : 9
123 : 0
foo : 0
: 0

static final Pattern LAST_NUMBER = Pattern.compile("\d+\D*$");
static int indexOfLastNumber(String s) {
Matcher m = LAST_NUMBER.matcher(s);
return m.find() ? m.start() : 0;
}

您可以使用Regex命名组获得它

public static int indexOfLastNumber(String text) {
Pattern pattern = Pattern.compile("(\d+)(?!.*\d)");
Matcher matcher = pattern.matcher(text);
return matcher.find() ? matcher.start() : -1;
}

我使用了@csalmhof答案中的测试用例,多亏了他

public static void main(String[] args) {
System.out.println(""987abc<*123"" + " index of lastNumberSet: " + indexOfLastNumber("987abc<*123"));
System.out.println(""987abc<*123abc"" + " index of lastNumberSet: " + indexOfLastNumber("987abc<*123abc"));
System.out.println(""987abc"" + " index of lastNumberSet: " + indexOfLastNumber("987abc"));
System.out.println(""abc987"" + " index of lastNumberSet: " + indexOfLastNumber("abc987"));
System.out.println(""987"" + " index of lastNumberSet: " + indexOfLastNumber("987"));
System.out.println("(Empty String)" + " index of lastNumberSet: " + indexOfLastNumber(""));
System.out.println(""abc"" + " index of lastNumberSet: " + indexOfLastNumber("abc"));
}

输出,-1表示没有数字的文本

"987abc<*123" index of lastNumberSet: 8
"987abc<*123abc" index of lastNumberSet: 8
"987abc" index of lastNumberSet: 0
"abc987" index of lastNumberSet: 3
"987" index of lastNumberSet: 0
(Empty String) index of lastNumberSet: -1
"abc" index of lastNumberSet: -1

注意:"1"位于字符串的索引9处。

如果你不想,没有必要为此使用RegEx。

像这样的方法应该可以完成任务:

public static int findLastNumbersIndex(String s) {
boolean numberFound = false;
boolean charBeforeNumberFound = false;
//start at the end of the String
int index = s.length() - 1;
//loop from the back to the front while there are more chars 
//and no nonDigit is found before a digit
while (index >= 0 && !charBeforeNumberFound) {
//when the first number was found, set the boolean flag
if (!numberFound && Character.isDigit(s.charAt(index))) {
numberFound = true;
}
//when already a number was found and there is any nonDigit stop the execution
if (numberFound && !Character.isDigit(s.charAt(index))) {
charBeforeNumberFound = true;
break;
}
index--;
}

return index + 1;
}

不同字符串的执行:

public static void main(String[] args) {
System.out.println(""987abc<*(123"" + " index of lastNumberSet: " + findLastNumbersIndex("987abc<*(123"));
System.out.println(""987abc<*(123abc"" + " index of lastNumberSet: " + findLastNumbersIndex("987abc<*(123abc"));
System.out.println(""987abc"" + " index of lastNumberSet: " + findLastNumbersIndex("987abc"));
System.out.println(""abc987"" + " index of lastNumberSet: " + findLastNumbersIndex("abc987"));
System.out.println(""987"" + " index of lastNumberSet: " + findLastNumbersIndex("987"));
System.out.println("(Empty String)" + " index of lastNumberSet: " + findLastNumbersIndex(""));
System.out.println(""abc"" + " index of lastNumberSet: " + findLastNumbersIndex("abc"));
}

返回此输出:

"987abc<*(123" index of lastNumberSet: 9
"987abc<*(123abc" index of lastNumberSet: 9
"987abc" index of lastNumberSet: 0
"abc987" index of lastNumberSet: 3
"987" index of lastNumberSet: 0
(Empty String) index of lastNumberSet: 0
"abc" index of lastNumberSet: 0

您可以使用带有捕获组的模式,如果存在匹配,则可以使用public int start(int group(来获取Matcher的捕获组的开始索引。

(d)d*D*$
  • (d)组1中捕获一个位数
  • d*匹配可选数字
  • D*匹配可选非数字
  • $字符串末尾

查看regex演示和Java演示

示例:

String[] strings = { "987abc<*(123", "", "123", "test", "abc123" };
Pattern pattern = Pattern.compile("(\d)\d*\D*$");
for (String s : strings) {
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
System.out.printf("'%s' --> %dn", s, matcher.start(1));
continue;
}
System.out.printf("'%s' --> %dn", s, 0);
}

输出

'987abc<*(123' --> 9
'' --> 0
'123' --> 0
'test' --> 0
'abc123' --> 3

相关内容

最新更新