![](/img/trans.png)
[英]Produce variable size digits without leading zeros with Java String format
[英]Java, Regex match first 10 digits in String, disregard leading zeros
我有興趣從長字符串中提取前10個數字而忽略前導零。 此外,如果只有零,則只返回1 0,如果沒有數字,則返回空字符串。 我希望一次性find
。
例如:
"abcd00111.g2012asd"
應匹配"1112012"
"aktr0011122222222222ddd"
應匹配"1112222222"
"asdas000000asdasds0000"
應與"0"
匹配 "adsads.cxzv.;asdasd"
應匹配""
這是我到目前為止所嘗試的: Ideone演示 - 代碼
Pattern p = Pattern.compile("[1-9]{1}+[0-9]{9}");
Matcher m = p.matcher(str);
if (m.find()) {
String match = m.group();
System.out.println(match);
}
問題是這個正則表達式在第一個非零之后需要9個連續數字,我需要任何9位數(其間可能是非數字字符)。
請注意,在代碼中我有if (m.find())
而不是while (m.find())
因為我希望在單次運行中找到匹配。
UPDATE
基於評論我明白,正則表達式不可能在單次運行中完成。
我想答案不一定是基於正則表達式,但最有效率,因為我將多次執行此方法。
一般情況下,單個 find
無法執行此操作。如果您知道連續數字序列的最大數量,則可以執行此操作,但如果不知道,則不可能,至少在Java 我錯了。 Kobi的評論顯示,單個正則表達式是可能的。 我將在此處復制評論: Pattern
類的支持級別。
哦,使用正則表達式可以捕獲10個數字,例如:
^[\\D0]*(\\d)\\D*(?:(\\d)\\D*(?:(\\d)\\D*(?:(\\d)\\D*(?#{6 more times}))?)?)?
,但確實很難看,而且擴展性不好。
但是,您仍然需要串聯組。 開頭的正則表達式中的邏輯非常好:由於greedy屬性,它將搜索所有前導零(如果有)之后的第一個非零數字,或者如果不存在則返回最后一個0。 -零位數。
如果你把關於效率的討論扔出門外,你想要短代碼:
String digitOnly = str.replaceAll("\\D+", "");
String noLeadingZero = digitOnly.replaceFirst("^0+", "");
String result = digitOnly.isEmpty() ? "" :
noLeadingZero.isEmpty() ? "0" :
noLeadingZero.substring(0, Math.min(noLeadingZero.length(), 10));
坦率地說,使用StringBuilder
循環遍歷字符串就足夠了,它應該比正則表達式解決方案更快。
StringBuilder output = new StringBuilder();
boolean hasDigit = false;
boolean leadingZero = true;
for (int i = 0; i < str.length() && output.length() < 10; i++) {
char currChar = str.charAt(i);
if ('0' <= currChar && currChar <= '9') {
hasDigit = true;
if (currChar != '0') {
output.append(currChar);
leadingZero = false;
} else if (!leadingZero) { // currChar == 0
output.append(currChar);
} // Ignore leading zero
}
}
String result = !hasDigit ? "" :
output.length() == 0 ? "0" :
output.toString();
性能測試代碼 。 請注意,您應該調整參數以使其類似於實際輸入,以便獲得良好的近似值。 我懷疑循環方法比任何涉及正則表達式的方法都要慢。 但是,這種差異僅在大規模上才有意義。
String test = "sdfsd0000234.432004gr23.022";
StringBuilder sb = new StringBuilder();
for(int i=0;i<test.length();i++) {
if(Character.isDigit(test.charAt(i)))
sb = sb.append(test.charAt(i));
}
String result = sb.toString();
result = result.replaceFirst("^0*", ""); //Remove leading zeros
System.out.println(result); //Will print 23443200423022
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.