यदि आप स्ट्रिंग को पार्स करने से पहले एक नंबर थे, तो आप कैसे जांचेंगे?
Integer.parseInt()
मोबाइल नंबरों को पार्स करने में विफल होंगे NumberFormatException
।
यदि आप स्ट्रिंग को पार्स करने से पहले एक नंबर थे, तो आप कैसे जांचेंगे?
Integer.parseInt()
मोबाइल नंबरों को पार्स करने में विफल होंगे NumberFormatException
।
जवाबों:
साथ अपाचे कॉमन्स लैंग 3.5 और अधिक: NumberUtils.isCreatable
या StringUtils.isNumeric
।
साथ अपाचे कॉमन्स लैंग 3.4 और नीचे: NumberUtils.isNumber
या StringUtils.isNumeric
।
तुम भी उपयोग कर सकते हैं StringUtils.isNumericSpace
जो रिटर्न true
रिक्त स्ट्रिंग के लिए और स्ट्रिंग में आंतरिक रिक्त स्थान पर ध्यान नहीं देता। एक अन्य तरीका यह है NumberUtils.isParsable
कि मूल रूप से चेक की संख्या जावा के अनुसार उपयोग करने योग्य है। (लिंक किए गए javadocs में प्रत्येक विधि के लिए विस्तृत उदाहरण हैं।)
StringUtils.isNumeric()
शायद यह उचित नहीं होगा क्योंकि यह केवल जाँचता है कि क्या स्ट्रिंग अंकों का अनुक्रम है। अधिकांश ints के लिए ठीक होगा, लेकिन दशमलव, समूह विभाजक, आदि के साथ संख्याओं के लिए ऐसा नहीं है
StringUtils
अग्रणी संकेतों का समर्थन नहीं करता है लेकिन आपको जांचना चाहिए NumberUtils.isCreatable
, यह नकारात्मक रूप से ठीक से समर्थन करता है।
यह आम तौर पर एक साधारण उपयोगकर्ता-परिभाषित फ़ंक्शन (यानी रोल-योर-ओन "इनेमरिक" फ़ंक्शन) के साथ किया जाता है।
कुछ इस तरह:
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e){
return false;
}
}
हालाँकि, यदि आप इस फ़ंक्शन को बहुत अधिक कह रहे हैं, और आप कई चेकों की अपेक्षा करते हैं कि संख्या नहीं होने के कारण विफल होने के बाद इस तंत्र का प्रदर्शन बहुत अच्छा नहीं होगा, क्योंकि आप प्रत्येक विफलता के लिए फेंके जा रहे अपवादों पर भरोसा कर रहे हैं, जो काफी महंगा ऑपरेशन है।
एक वैकल्पिक दृष्टिकोण संख्या होने की वैधता की जांच करने के लिए एक नियमित अभिव्यक्ति का उपयोग करने के लिए हो सकता है:
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
उपरोक्त RegEx तंत्र के साथ सावधान रहें, हालांकि, यदि आप गैर-अरबी अंकों (यानी 0 से 9 के अलावा अंक) का उपयोग कर रहे हैं तो यह विफल हो जाएगा। इसका कारण यह है कि RegEx का "\ d" भाग केवल [0-9] से मेल खाएगा और प्रभावी रूप से अंतर्राष्ट्रीय रूप से अवगत नहीं है। (इस ओर इशारा करने के लिए ओरेगनगॉस्ट का धन्यवाद!)
या यहां तक कि एक अन्य विकल्प जावा के अंतर्निहित java.text.NumberFormat ऑब्जेक्ट का उपयोग करना है, यह देखने के लिए कि स्ट्रिंग को पार्स करने के बाद, स्ट्रिंग के अंत में पार्सर की स्थिति है। यदि यह है, तो हम मान सकते हैं कि संपूर्ण स्ट्रिंग संख्यात्मक है:
public static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
.
आपके regex में किसी भी वर्ण का मिलान होगा, न कि केवल दशमलव विभाजक वर्ण से।
यदि आप Android पर हैं, तो आपको उपयोग करना चाहिए:
android.text.TextUtils.isDigitsOnly(CharSequence str)
इसे सरल रखें । ज्यादातर हर कोई "री-प्रोग्राम" (एक ही बात) कर सकता है।
.
,-
जावा 8 लंबोदर भाव।
String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
जैसा कि @CraigTP ने अपने उत्कृष्ट उत्तर में उल्लेख किया था, मेरे पास अपवाद का उपयोग करने के लिए इसी तरह के प्रदर्शन की चिंता है कि क्या परीक्षण संख्यात्मक है या नहीं। तो मैं अंत में स्ट्रिंग और उपयोग को विभाजित करता हूं java.lang.Character.isDigit()
।
public static boolean isNumeric(String str)
{
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
}
Javadoc के अनुसार , Character.isDigit(char)
गैर-लैटिन अंकों को सही ढंग से पहचान लेगा। प्रदर्शन के लिहाज से, मुझे लगता है कि एक सरल एन संख्या की तुलना जहां एन स्ट्रिंग में वर्णों की संख्या है, एक रेगेक्स मिलान करने की तुलना में अधिक कम्प्यूटेशनल रूप से कुशल होगा।
अद्यतन: जैसा कि टिप्पणी में जीन-फ्रांस्वा कॉर्बेट द्वारा कहा गया है, उपरोक्त कोड केवल सकारात्मक पूर्णांक को मान्य करेगा, जो मेरे उपयोग के मामले के बहुमत को कवर करता है। नीचे अद्यतन कोड है जो आपके सिस्टम में उपयोग किए गए डिफ़ॉल्ट लोकेल के अनुसार दशमलव संख्याओं को सही ढंग से मान्य करता है, इस धारणा के साथ कि दशमलव विभाजक केवल एक बार स्ट्रिंग में होता है।
public static boolean isStringNumeric( String str )
{
DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
char localeMinusSign = currentLocaleSymbols.getMinusSign();
if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;
boolean isDecimalSeparatorFound = false;
char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();
for ( char c : str.substring( 1 ).toCharArray() )
{
if ( !Character.isDigit( c ) )
{
if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
{
isDecimalSeparatorFound = true;
continue;
}
return false;
}
}
return true;
}
toCharArray()
स्ट्रिंग ऑब्जेक्ट में सरणी की एक प्रति बनाएगी क्योंकि स्ट्रिंग्स अपरिवर्तनीय हैं। charAt(int index)
स्ट्रिंग ऑब्जेक्ट पर सीधे विधि का उपयोग करने के लिए संभवतः तेज है ।
StringIndexOutOfBoundsException
लंबाई के साथ एक स्ट्रिंग पारित होने पर उत्पन्न होगा 0. के साथ तय किया जा सकता हैif(str.length() == 0) return false;
Google का अमरूद पुस्तकालय ऐसा करने के लिए एक अच्छा सहायक तरीका प्रदान करता है Ints.tryParse
:। यदि आप स्ट्रिंग को वैध पूर्णांक तक पार्स नहीं करते हैं तो आप इसका उपयोग करते हैं Integer.parseInt
लेकिन यह null
अपवाद को फेंकने के बजाय वापस लौटता है । ध्यान दें कि यह इंटेगर को लौटाता है, इंट नहीं, इसलिए आपको इसे वापस ऑटो में बदलना होगा।
उदाहरण:
String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);
int i1 = -1;
if (oInt1 != null) {
i1 = oInt1.intValue();
}
int i2 = -1;
if (oInt2 != null) {
i2 = oInt2.intValue();
}
System.out.println(i1); // prints 22
System.out.println(i2); // prints -1
हालांकि, वर्तमान रिलीज के रूप में - अमरूद r11 - यह अभी भी @ बटा चिह्नित है।
मैंने इसे बेंचमार्क नहीं किया है। स्रोत कोड को देखते हुए बहुत अधिक पवित्रता की जाँच से कुछ ओवरहेड है लेकिन अंत में वे Character.digit(string.charAt(idx))
इसी तरह का उपयोग करते हैं , लेकिन थोड़ा अलग, ऊपर @ इब्राहिम से उत्तर। उनके कार्यान्वयन में कवर के तहत ओवरहेड को संभालने के लिए कोई अपवाद नहीं है।
अपने मूल्यों को मान्य करने के लिए अपवाद का उपयोग न करें। Apache NumberUtils के बजाय Util libs का प्रयोग करें:
NumberUtils.isNumber(myStringValue);
संपादित करें :
कृपया ध्यान दें कि, यदि आपका स्ट्रिंग 0 से शुरू होता है, तो NumberUtils आपके मान को हेक्साडेसिमल के रूप में व्याख्या करेगा।
NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
Number.isNumber()
।
Number.isNumber()
के पहले संस्करण से मौजूद था, दिनांक 24 सितंबर 12 17:01 पर।
हर कोई अपवाद / रेगेक्स समाधान के लिए क्यों जोर दे रहा है?
जबकि मैं समझ सकता हूं कि अधिकांश लोग कोशिश / पकड़ का उपयोग करने के साथ ठीक हैं, यदि आप इसे अक्सर करना चाहते हैं ... तो यह बहुत कर हो सकता है।
मैंने यहाँ क्या किया था regex, parseNumber () मेथड्स, और ऐरे सर्चिंग मेथड को देखने के लिए जो सबसे अधिक कुशल था। इस बार, मैंने केवल पूर्णांक संख्याओं को देखा।
public static boolean isNumericRegex(String str) {
if (str == null)
return false;
return str.matches("-?\\d+");
}
public static boolean isNumericArray(String str) {
if (str == null)
return false;
char[] data = str.toCharArray();
if (data.length <= 0)
return false;
int index = 0;
if (data[0] == '-' && data.length > 1)
index = 1;
for (; index < data.length; index++) {
if (data[index] < '0' || data[index] > '9') // Character.isDigit() can go here too.
return false;
}
return true;
}
public static boolean isNumericException(String str) {
if (str == null)
return false;
try {
/* int i = */ Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
गति के परिणाम मुझे मिले:
Done with: for (int i = 0; i < 10000000; i++)...
With only valid numbers ("59815833" and "-59815833"):
Array numeric took 395.808192 ms [39.5808192 ns each]
Regex took 2609.262595 ms [260.9262595 ns each]
Exception numeric took 428.050207 ms [42.8050207 ns each]
// Negative sign
Array numeric took 355.788273 ms [35.5788273 ns each]
Regex took 2746.278466 ms [274.6278466 ns each]
Exception numeric took 518.989902 ms [51.8989902 ns each]
// Single value ("1")
Array numeric took 317.861267 ms [31.7861267 ns each]
Regex took 2505.313201 ms [250.5313201 ns each]
Exception numeric took 239.956955 ms [23.9956955 ns each]
// With Character.isDigit()
Array numeric took 400.734616 ms [40.0734616 ns each]
Regex took 2663.052417 ms [266.3052417 ns each]
Exception numeric took 401.235906 ms [40.1235906 ns each]
With invalid characters ("5981a5833" and "a"):
Array numeric took 343.205793 ms [34.3205793 ns each]
Regex took 2608.739933 ms [260.8739933 ns each]
Exception numeric took 7317.201775 ms [731.7201775 ns each]
// With a single character ("a")
Array numeric took 291.695519 ms [29.1695519 ns each]
Regex took 2287.25378 ms [228.725378 ns each]
Exception numeric took 7095.969481 ms [709.5969481 ns each]
With null:
Array numeric took 214.663834 ms [21.4663834 ns each]
Regex took 201.395992 ms [20.1395992 ns each]
Exception numeric took 233.049327 ms [23.3049327 ns each]
Exception numeric took 6603.669427 ms [660.3669427 ns each] if there is no if/null check
अस्वीकरण: मैं दावा नहीं कर रहा हूं कि ये विधियां 100% अनुकूलित हैं, वे सिर्फ डेटा के प्रदर्शन के लिए हैं
अपवाद जीते गए अगर और केवल अगर संख्या 4 वर्ण या उससे कम है, और हर स्ट्रिंग हमेशा एक संख्या है ... किस मामले में, यहां तक कि एक चेक भी क्यों है?
संक्षेप में, यह बहुत ही दर्दनाक है यदि आप कोशिश / पकड़ के साथ अक्सर अवैध संख्या में चलते हैं, जो समझ में आता है। एक महत्वपूर्ण नियम जिसका मैं हमेशा पालन करता हूं वह है कार्यक्रम के प्रवाह के लिए कोशिश / पकड़ का उपयोग करना । यह एक उदाहरण है क्यों।
दिलचस्प है, सरल अगर चार <0 || > 9 लिखना बेहद सरल था, याद रखने में आसान (और कई भाषाओं में काम करना चाहिए) और लगभग सभी परीक्षा परिदृश्यों को जीतता है।
केवल नकारात्मक पक्ष यह है कि मैं अनुमान लगा रहा हूं कि Integer.parseInt () गैर ASCII संख्या को संभाल सकता है, जबकि सरणी खोज विधि नहीं है।
उन लोगों के लिए जो मैंने कहा कि चरित्र सरणी एक को याद रखना आसान है, अगर आपको पता है कि कोई नकारात्मक संकेत नहीं है, तो आप आसानी से इस तरह से संघनित कुछ के साथ दूर हो सकते हैं:
public static boolean isNumericArray(String str) {
if (str == null)
return false;
for (char c : str.toCharArray())
if (c < '0' || c > '9')
return false;
return true;
अंतिम नोट के रूप में, मैं सभी वोटों के साथ स्वीकृत उदाहरण में एसिगमेंट ऑपरेटर के बारे में उत्सुक था। के कार्य में जोड़ना
double d = Double.parseDouble(...)
न केवल बेकार है क्योंकि आप भी मूल्य का उपयोग नहीं करते हैं, लेकिन यह प्रसंस्करण समय बर्बाद करता है और कुछ नैनोसेकंड (जिससे परीक्षणों में 100-200 एमएस की वृद्धि हुई) द्वारा रनटाइम में वृद्धि हुई है। मैं यह नहीं देख सकता कि कोई भी ऐसा क्यों करेगा क्योंकि यह वास्तव में प्रदर्शन को कम करने के लिए अतिरिक्त काम है।
आपको लगता है कि इसे अनुकूलित किया जाएगा ... हालांकि शायद मुझे बायटेकोड की जांच करनी चाहिए और देखना चाहिए कि कंपाइलर क्या कर रहा है। यह स्पष्ट नहीं करता है कि यह हमेशा मेरे लिए लंबा क्यों दिखा, हालांकि अगर किसी तरह इसे अनुकूलित किया जाता है ... तो मुझे आश्चर्य है कि क्या चल रहा है। एक नोट के रूप में: लंबे समय तक, मेरा मतलब है कि 10000000 पुनरावृत्तियों के लिए परीक्षण चलाना, और उस कार्यक्रम को कई बार चलाना (10x +) हमेशा इसे धीमा दिखाया गया।
EDIT: Character.isDigit के लिए एक परीक्षण अपडेट किया गया ()
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(.\\d+)?");
}
क्रेगटीपी की नियमित अभिव्यक्ति (ऊपर दिखाई गई) कुछ झूठी सकारात्मकता पैदा करती है। जैसे "23y4" को एक संख्या के रूप में गिना जाएगा क्योंकि '।' किसी भी वर्ण को दशमलव बिंदु से नहीं मिलाता है।
इसके अलावा यह एक अग्रणी '+' के साथ किसी भी संख्या को अस्वीकार कर देगा
एक विकल्प जो इन दो छोटी समस्याओं से बचा जाता है
public static boolean isNumeric(String str)
{
return str.matches("[+-]?\\d*(\\.\\d+)?");
}
true
एक एकल प्लस के लिए "+"
या ऋण "-"
, और false
के लिए"0."
matches("-?\\d+([.]\\d+)?")
हम दिए गए स्ट्रिंग से सभी संख्याओं को बदलने की कोशिश कर सकते हैं ("") अर्थात रिक्त स्थान और यदि उसके बाद स्ट्रिंग की लंबाई शून्य है तो हम कह सकते हैं कि दिए गए स्ट्रिंग में केवल संख्याएँ हैं। [अगर आपको यह उत्तर उपयोगी लगा तो कृपया इसे वोट करने पर विचार करें] उदाहरण:
boolean isNumber(String str){
if(str.length() == 0)
return false; //To check if string is empty
if(str.charAt(0) == '-')
str = str.replaceFirst("-","");// for handling -ve numbers
System.out.println(str);
str = str.replaceFirst("\\.",""); //to check if it contains more than one decimal points
if(str.length() == 0)
return false; // to check if it is empty string after removing -ve sign and decimal point
System.out.println(str);
return str.replaceAll("[0-9]","").length() == 0;
}
""
एक नंबर लेकिन है "3.14"
और "-1"
नहीं कर रहे हैं?
आप उपयोग कर सकते हैं NumberFormat#parse
:
try
{
NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
// Not a number.
}
value
।
यदि आप एंड्रॉइड ऐप को विकसित करने के लिए जावा का उपयोग कर रहे हैं, तो आप TextUtils.isDigitsOnly फ़ंक्शन का उपयोग कर सकते हैं ।
यहाँ समस्या का मेरा जवाब था।
किसी भी प्रकार के पार्सर के साथ किसी भी स्ट्रिंग को पार्स करने के लिए उपयोग कर सकते हैं, जो सभी सुविधा विधि को पकड़ें isParsable(Object parser, String str)
:। पार्सर एक Class
या एक हो सकता है object
। इससे आप अपने द्वारा लिखे गए कस्टम पार्सर का उपयोग कर सकते हैं और हमेशा के लिए काम करना चाहिए, जैसे:
isParsable(Integer.class, "11");
isParsable(Double.class, "11.11");
Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");
यहां विधि विवरण के साथ मेरा कोड पूरा है।
import java.lang.reflect.*;
/**
* METHOD: isParsable<p><p>
*
* This method will look through the methods of the specified <code>from</code> parameter
* looking for a public method name starting with "parse" which has only one String
* parameter.<p>
*
* The <code>parser</code> parameter can be a class or an instantiated object, eg:
* <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a
* <code>Class</code> type then only static methods are considered.<p>
*
* When looping through potential methods, it first looks at the <code>Class</code> associated
* with the <code>parser</code> parameter, then looks through the methods of the parent's class
* followed by subsequent ancestors, using the first method that matches the criteria specified
* above.<p>
*
* This method will hide any normal parse exceptions, but throws any exceptions due to
* programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>
* parameter which has no matching parse methods, a NoSuchMethodException will be thrown
* embedded within a RuntimeException.<p><p>
*
* Example:<br>
* <code>isParsable(Boolean.class, "true");<br>
* isParsable(Integer.class, "11");<br>
* isParsable(Double.class, "11.11");<br>
* Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>
* isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>
* <p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @throws java.lang.NoSuchMethodException If no such method is accessible
*/
public static boolean isParsable(Object parser, String str) {
Class theClass = (parser instanceof Class? (Class)parser: parser.getClass());
boolean staticOnly = (parser == theClass), foundAtLeastOne = false;
Method[] methods = theClass.getMethods();
// Loop over methods
for (int index = 0; index < methods.length; index++) {
Method method = methods[index];
// If method starts with parse, is public and has one String parameter.
// If the parser parameter was a Class, then also ensure the method is static.
if(method.getName().startsWith("parse") &&
(!staticOnly || Modifier.isStatic(method.getModifiers())) &&
Modifier.isPublic(method.getModifiers()) &&
method.getGenericParameterTypes().length == 1 &&
method.getGenericParameterTypes()[0] == String.class)
{
try {
foundAtLeastOne = true;
method.invoke(parser, str);
return true; // Successfully parsed without exception
} catch (Exception exception) {
// If invoke problem, try a different method
/*if(!(exception instanceof IllegalArgumentException) &&
!(exception instanceof IllegalAccessException) &&
!(exception instanceof InvocationTargetException))
continue; // Look for other parse methods*/
// Parse method refuses to parse, look for another different method
continue; // Look for other parse methods
}
}
}
// No more accessible parse method could be found.
if(foundAtLeastOne) return false;
else throw new RuntimeException(new NoSuchMethodException());
}
/**
* METHOD: willParse<p><p>
*
* A convienence method which calls the isParseable method, but does not throw any exceptions
* which could be thrown through programatic errors.<p>
*
* Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic
* errors can be caught in development, unless the value of the <code>parser</code> parameter is
* unpredictable, or normal programtic exceptions should be ignored.<p>
*
* See {@link #isParseable(Object, String) isParseable} for full description of method
* usability.<p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @see #isParseable(Object, String) for full description of method usability
*/
public static boolean willParse(Object parser, String str) {
try {
return isParsable(parser, str);
} catch(Throwable exception) {
return false;
}
}
नकारात्मक संख्या और वैज्ञानिक संकेतन से बचने की कोशिश और प्रदर्शन से बचने के लिए एक अच्छा प्रदर्शन करने वाला दृष्टिकोण।
Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value )
{
return value != null && PATTERN.matcher( value ).matches();
}
यहां यह जांचने के लिए मेरी कक्षा है कि क्या कोई स्ट्रिंग संख्यात्मक है। यह संख्यात्मक तार भी ठीक करता है:
हेयर यू गो...
public class NumUtils {
/**
* Transforms a string to an integer. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/
static String makeToInteger(String str) {
String s = str;
double d;
d = Double.parseDouble(makeToDouble(s));
int i = (int) (d + 0.5D);
String retStr = String.valueOf(i);
System.out.printf(retStr + " ");
return retStr;
}
/**
* Transforms a string to an double. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/
static String makeToDouble(String str) {
Boolean dotWasFound = false;
String orgStr = str;
String retStr;
int firstDotPos = 0;
Boolean negative = false;
//check if str is null
if(str.length()==0){
str="0";
}
//check if first sign is "-"
if (str.charAt(0) == '-') {
negative = true;
}
//check if str containg any number or else set the string to '0'
if (!str.matches(".*\\d+.*")) {
str = "0";
}
//Replace ',' with '.' (for some european users who use the ',' as decimal separator)
str = str.replaceAll(",", ".");
str = str.replaceAll("[^\\d.]", "");
//Removes the any second dots
for (int i_char = 0; i_char < str.length(); i_char++) {
if (str.charAt(i_char) == '.') {
dotWasFound = true;
firstDotPos = i_char;
break;
}
}
if (dotWasFound) {
String befDot = str.substring(0, firstDotPos + 1);
String aftDot = str.substring(firstDotPos + 1, str.length());
aftDot = aftDot.replaceAll("\\.", "");
str = befDot + aftDot;
}
//Removes zeros from the begining
double uglyMethod = Double.parseDouble(str);
str = String.valueOf(uglyMethod);
//Removes the .0
str = str.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");
retStr = str;
if (negative) {
retStr = "-"+retStr;
}
return retStr;
}
static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
}
रेगेक्स मैचिंग
यहां एक और उदाहरण उन्नत "क्रेगटीपी" रेगेक्स को अधिक मान्यताओं के साथ मिलान किया गया है।
public static boolean isNumeric(String str)
{
return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
रेगेक्स टेस्ट
1 -- **VALID**
1. -- INVALID
1.. -- INVALID
1.1 -- **VALID**
1.1.1 -- INVALID
-1 -- **VALID**
--1 -- INVALID
-1. -- INVALID
-1.1 -- **VALID**
-1.1.1 -- INVALID
अपवाद महंगे हैं, लेकिन इस मामले में RegEx अधिक समय लेता है। नीचे दिए गए कोड में दो कार्यों का एक सरल परीक्षण दिखाया गया है - एक अपवाद का उपयोग करके और एक रेगेक्स का उपयोग करके। मेरी मशीन पर RegEx संस्करण अपवाद से 10 गुना धीमा है।
import java.util.Date;
public class IsNumeric {
public static boolean isNumericOne(String s) {
return s.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumericTwo(String s) {
try {
Double.parseDouble(s);
return true;
} catch (Exception e) {
return false;
}
}
public static void main(String [] args) {
String test = "12345.F";
long before = new Date().getTime();
for(int x=0;x<1000000;++x) {
//isNumericTwo(test);
isNumericOne(test);
}
long after = new Date().getTime();
System.out.println(after-before);
}
}
// कृपया नीचे दिए गए कोड की जाँच करें
public static boolean isDigitsOnly(CharSequence str) {
final int len = str.length();
for (int i = 0; i < len; i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
// only int
public static boolean isNumber(int num)
{
return (num >= 48 && c <= 57); // 0 - 9
}
// is type of number including . - e E
public static boolean isNumber(String s)
{
boolean isNumber = true;
for(int i = 0; i < s.length() && isNumber; i++)
{
char c = s.charAt(i);
isNumber = isNumber & (
(c >= '0' && c <= '9') || (c == '.') || (c == 'e') || (c == 'E') || (c == '')
);
}
return isInteger;
}
// is type of number
public static boolean isInteger(String s)
{
boolean isInteger = true;
for(int i = 0; i < s.length() && isInteger; i++)
{
char c = s.charAt(i);
isInteger = isInteger & ((c >= '0' && c <= '9'));
}
return isInteger;
}
public static boolean isNumeric(String s)
{
try
{
Double.parseDouble(s);
return true;
}
catch (Exception e)
{
return false;
}
}
इस जाँच के लिए यह एक सरल उदाहरण है:
public static boolean isNumericString(String input) {
boolean result = false;
if(input != null && input.length() > 0) {
char[] charArray = input.toCharArray();
for(char c : charArray) {
if(c >= '0' && c <= '9') {
// it is a digit
result = true;
} else {
result = false;
break;
}
}
}
return result;
}
आप java.util.Scanner ऑब्जेक्ट का उपयोग कर सकते हैं।
public static boolean isNumeric(String inputData) {
Scanner sc = new Scanner(inputData);
return sc.hasNextInt();
}
मैंने वैज्ञानिक संकेतन और दशमलव विभाजक के रूप में डॉट और अल्पविराम दोनों को स्वीकार करने के लिए क्रेगटीपी के समाधान को संशोधित किया
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
उदाहरण
var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546"); // true
re.test("-6546355e-4456"); // true
re.test("-6546.355e-4456"); // true, though debatable
re.test("-6546.35.5e-4456"); // false
re.test("-6546.35.5e-4456.6"); // false
यही कारण है कि मैं .NET में Try * के दृष्टिकोण को पसंद करता हूं। पारंपरिक पारस पद्धति के अलावा, जो जावा की तरह है, आपके पास एक ट्रायपर्स विधि भी है। मैं जावा सिंटैक्स (मापदंडों के बाहर?) में अच्छा नहीं हूं, इसलिए कृपया निम्न प्रकार के छद्म कोड के रूप में व्यवहार करें। हालांकि यह अवधारणा स्पष्ट करना चाहिए।
boolean parseInteger(String s, out int number)
{
try {
number = Integer.parseInt(myString);
return true;
} catch(NumberFormatException e) {
return false;
}
}
उपयोग:
int num;
if (parseInteger("23", out num)) {
// Do something with num.
}
इसे पार्स करें (यानी के साथ Integer#parseInt
) और बस अपवाद को पकड़ें। =)
स्पष्ट करने के लिए: parseInt फ़ंक्शन यह जाँचता है कि क्या यह किसी भी स्थिति में नंबर को पार्स कर सकता है (जाहिर है) और यदि आप इसे वैसे भी पार्स करना चाहते हैं, तो आप वास्तव में पार्सिंग करके कोई प्रदर्शन हिट नहीं लेने जा रहे हैं।
यदि आप इसे पार्स नहीं करना चाहते हैं (या इसे बहुत कम पार्स करते हैं, तो शायद ही कभी) आप इसे अलग तरीके से करने की इच्छा कर सकते हैं।
आप Apache Commons Lang से NumberUtils.isCreatable () का उपयोग कर सकते हैं ।
चूंकि NumberUtils.isNumber 4.0 में पदावनत किया जाएगा, इसलिए इसके बजाय NumberUtils.isCreatable () का उपयोग करें।
जावा 8 स्ट्रीम, लैम्ब्डा अभिव्यक्ति, कार्यात्मक इंटरफ़ेस
सभी मामलों को संभाला ( स्ट्रिंग रिक्त, स्ट्रिंग खाली आदि )
String someString = null; // something="", something="123abc", something="123123"
boolean isNumeric = Stream.of(someString)
.filter(s -> s != null && !s.isEmpty())
.filter(Pattern.compile("\\D").asPredicate().negate())
.mapToLong(Long::valueOf)
.boxed()
.findAny()
.isPresent();
मैंने किसी भी एपीआई का उपयोग किए बिना संख्या और दशमलव की जांच करने के लिए कुछ शर्तों को सचित्र किया है,
फिक्स लंबाई 1 अंकों की संख्या की जाँच करें
Character.isDigit(char)
फिक्स लंबाई संख्या की जाँच करें (मान लें कि लंबाई 6 है)
String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");
बीच लंबाई की संख्या की जाँच करें (मान लें 4 से 6 लंबाई)
// {n,m} n <= length <= m
String number = "132452";
if(number.matches("([0-9]{4,6})"))
System.out.println("Number Identified between 4 to 6 length");
String number = "132";
if(!number.matches("([0-9]{4,6})"))
System.out.println("Number not in length range or different format");
बीच में भिन्न लंबाई दशमलव संख्या जांचें (मान लें 4 से 7 लंबाई)
// It will not count the '.' (Period) in length
String decimal = "132.45";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "1.12";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "1234";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "-10.123";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "123..4";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
String decimal = "132";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
String decimal = "1.1";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
आशा है कि यह कई लोगों की मदद करेगा।
अन्य उत्तरों के आधार पर मैंने अपना लिखा और यह अपवाद जाँच के साथ पैटर्न या पार्सिंग का उपयोग नहीं करता है।
यह अधिकतम एक माइनस साइन की जाँच करता है और अधिकतम एक दशमलव बिंदु की जाँच करता है।
यहाँ कुछ उदाहरण और उनके परिणाम दिए गए हैं:
"1", "-1", "-1.5" और "-1.556" सही है
"1..5", "1A.5", "1.5D", "-" और "- 1" झूठे लौटते हैं
नोट: यदि आपको जरूरत है तो आप लोकेल पैरामीटर को स्वीकार करने के लिए इसे संशोधित कर सकते हैं और इसे DecimalFormatSymbols.getInstance () कॉल में वर्तमान के बजाय एक विशिष्ट लोकेल का उपयोग कर सकते हैं।
public static boolean isNumeric(final String input) {
//Check for null or blank string
if(input == null || input.isBlank()) return false;
//Retrieve the minus sign and decimal separator characters from the current Locale
final var localeMinusSign = DecimalFormatSymbols.getInstance().getMinusSign();
final var localeDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
//Check if first character is a minus sign
final var isNegative = input.charAt(0) == localeMinusSign;
//Check if string is not just a minus sign
if (isNegative && input.length() == 1) return false;
var isDecimalSeparatorFound = false;
//If the string has a minus sign ignore the first character
final var startCharIndex = isNegative ? 1 : 0;
//Check if each character is a number or a decimal separator
//and make sure string only has a maximum of one decimal separator
for (var i = startCharIndex; i < input.length(); i++) {
if(!Character.isDigit(input.charAt(i))) {
if(input.charAt(i) == localeDecimalSeparator && !isDecimalSeparatorFound) {
isDecimalSeparatorFound = true;
} else return false;
}
}
return true;
}
यहाँ दो तरीके हैं जो काम कर सकते हैं। (अपवाद का उपयोग किए बिना)। नोट: जावा डिफ़ॉल्ट रूप से एक पास-बाय-वैल्यू है और एक स्ट्रिंग का मूल्य स्ट्रिंग के ऑब्जेक्ट डेटा का पता है। तो, जब आप कर रहे हैं
stringNumber = stringNumber.replaceAll(" ", "");
आपके पास रिक्त स्थान नहीं होने के लिए इनपुट मान बदल गया है। आप चाहें तो उस लाइन को हटा सकते हैं।
private boolean isValidStringNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if(!Character.isDigit(charNumber[i]))
{
return false;
}
}
return true;
}
यदि आप फ़्लोट्स की अनुमति देना चाहते हैं, तो यहां एक और तरीका है। यह विधि कथित रूप से 1,123,123,123,123,123.123 पास करने के लिए फॉर्म में संख्याओं की अनुमति देती है, और मुझे लगता है कि इसे सुनिश्चित करने के लिए इसे और परीक्षण की आवश्यकता है।
private boolean isValidStringTrueNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
int countOfDecimalPoint = 0;
boolean decimalPointPassed = false;
boolean commaFound = false;
int countOfDigitsBeforeDecimalPoint = 0;
int countOfDigitsAfterDecimalPoint =0 ;
int commaCounter=0;
int countOfDigitsBeforeFirstComma = 0;
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if((commaCounter>3)||(commaCounter<0))
{
return false;
}
if(!Character.isDigit(charNumber[i]))//Char is not a digit.
{
if(charNumber[i]==',')
{
if(decimalPointPassed)
{
return false;
}
commaFound = true;
//check that next three chars are only digits.
commaCounter +=3;
}
else if(charNumber[i]=='.')
{
decimalPointPassed = true;
countOfDecimalPoint++;
}
else
{
return false;
}
}
else //Char is a digit.
{
if ((commaCounter>=0)&&(commaFound))
{
if(!decimalPointPassed)
{
commaCounter--;
}
}
if(!commaFound)
{
countOfDigitsBeforeFirstComma++;
}
if(!decimalPointPassed)
{
countOfDigitsBeforeDecimalPoint++;
}
else
{
countOfDigitsAfterDecimalPoint++;
}
}
}
if((commaFound)&&(countOfDigitsBeforeFirstComma>3))
{
return false;
}
if(countOfDecimalPoint>1)
{
return false;
}
if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0)))
{
return false;
}
return true;
}