[英]How to match a long with Java regex?
我知道我可以使用Pattern.compile("\\\\d*");
匹配數字Pattern.compile("\\\\d*");
但它不能處理長的最小/最大值。
對於與異常相關的性能問題,我不想嘗試解析長期,除非它真的很長。
if ( LONG_PATTERN.matcher(timestampStr).matches() ) {
long timeStamp = Long.parseLong(timestampStr);
return new Date(timeStamp);
} else {
LOGGER.error("Can't convert " + timestampStr + " to a Date because it is not a timestamp! -> ");
return null;
}
我的意思是我不想要任何try / catch塊,並且我不想得到像“564654954654464654654567879865132154778”這樣長的異常,這超出了常規Java long的大小。
有人有一個模式來處理原始java類型的這種需求嗎? JDK是否提供了自動處理它的東西? Java中是否存在故障安全解析機制?
謝謝
編輯:請假設“壞長字符串”不是例外情況。 我不是要求一個基准,我在這里代表一個長期的正則表達式,僅此而已。 我知道正則表達式檢查所需的額外時間,但至少我的長解析將始終是常量並且永遠不會依賴於“壞長字符串”的百分比
我再也找不到鏈接,但StackOverflow上有一個很好的解析基准,它清楚地表明重用編譯正則表達式的sams非常快,比拋出異常快很多,因此只有一小部分異常會使系統變慢與額外的正則表達式檢查。
一的最小avlue long
是-9,223,372,036,854,775,808
,並且最大值為9,223,372,036,854,775,807
。 所以,最多19位數。 所以, \\d{1,19}
應該讓你到那里,也許帶有一個可選的-
,並用^
和$
來匹配字符串的末尾。
粗略地說 :
Pattern LONG_PATTERN = Pattern.compile("^-?\\d{1,19}$");
......或者沿着這些方向的東西,假設你不允許使用逗號(或者已經刪除了它們)。
正如gexicide在評論中指出的那樣,上面允許一小部分(比較)無效值范圍,例如9,999,999,999,999,999,999
。 您可以使用正則表達式進行更復雜的處理,或者只是接受以上內容將清除絕大多數無效數字,從而減少解析異常的數量。
這個正則表達式應該做你需要的:
^(-9223372036854775808|0)$|^((-?)((?!0)\\d{1,18}|[1-8]\\d{18}|9[0-1]\\d{17}|92[0-1]\\d{16}|922[0-2]\\d{15}|9223[0-2]\\d{14}|92233[0-6]\\d{13}|922337[0-1]\\d{12}|92233720[0-2]\\d{10}|922337203[0-5]\\d{9}|9223372036[0-7]\\d{8}|92233720368[0-4]\\d{7}|922337203685[0-3]\\d{6}|9223372036854[0-6]\\d{5}|92233720368547[0-6]\\d{4}|922337203685477[0-4]\\d{3}|9223372036854775[0-7]\\d{2}|922337203685477580[0-7]))$
但是這個正則表達式不會驗證其他符號,如+
, L
, _
等。如果您需要驗證所有可能的Long值,則需要升級此regexp。
除非經常發生這種情況,否則只需捕獲NumberFormatException。
另一種方法是使用只允許長文字的模式。 這種模式可能非常復雜。
第三種方法是首先將數字解析為BigInt。 然后,您可以將它與Long.MAX_VALUE和Long.MIN_VALUE進行比較,以檢查它是否在long的范圍內。 然而,這也可能是昂貴的。
另請注意:解析long很快,它是一種非常優化的方法(例如,嘗試在一個步驟中解析兩個數字)。 應用模式匹配可能比執行解析更加昂貴。 解析的唯一問題是拋出NumberFormatException。 因此,如果特殊情況不經常發生,那么簡單地捕獲異常就是最好的方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.