जावा स्ट्रिंग - देखें कि क्या एक स्ट्रिंग में केवल संख्याएँ हैं और अक्षर नहीं


196

मेरे पास एक स्ट्रिंग है जिसे मैं अपने पूरे आवेदन में लोड करता हूं, और यह संख्याओं से अक्षरों और ऐसे में बदलता है। मेरे पास ifयह देखने के लिए एक सरल कथन है कि क्या इसमें अक्षर या संख्याएँ हैं लेकिन, कुछ सही ढंग से काम नहीं कर रहा है। यहाँ एक स्निपेट है।

String text = "abc"; 
String number; 

if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
    number = text; 
}

यद्यपि textचर में अक्षर नहीं होते हैं, लेकिन स्थिति वापस आ जाती है true। और प्रक्रिया के क्रम में &&होने के लिए दोनों स्थितियों के रूप में विकसित होना चाहिएtruenumber = text;

==============================

उपाय:

मैं इस प्रश्न पर एक टिप्पणी द्वारा प्रदान किए गए इस निम्नलिखित कोड का उपयोग करके इसे हल करने में सक्षम था। अन्य सभी पोस्ट भी मान्य हैं!

मैंने जो काम किया वह पहली टिप्पणी से आया। यद्यपि प्रदान किए गए सभी उदाहरण कोड मान्य लगते हैं!

String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}

5
इसमें इनपुट के रूप में एक regexp नहीं है। matches("\\d{2,}")या तो का उपयोग करें Patternऔर एक के साथ प्रयास करें औरMatcher
Guillaume Polet

क्या स्ट्रिंग में दशमलव मान या केवल पूर्णांक मान हो सकते हैं?
छद्ममोरल

3
आप text.length ()> 2 क्यों चेक कर रहे हैं? क्या कारण है?
कोड सरगर्मी

1
@RedHatcc Pattern.matches("[a-zA-Z]+", text) == falseको सरलीकृत किया जा सकता है!Pattern.matches("[a-zA-Z]+", text)
SARose

2
जावा स्ट्रीमिंग एपीआई boolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x));फॉर्म Max Malyshपोस्ट का उपयोग करना ।
यश

जवाबों:


354

यदि आप संख्या को पाठ के रूप में संसाधित कर रहे हैं, तो बदलें:

if (text.contains("[a-zA-Z]+") == false && text.length() > 2){

सेवा:

if (text.matches("[0-9]+") && text.length() > 2) {

यह जांचने के बजाय कि स्ट्रिंग में वर्णानुक्रमिक वर्ण नहीं हैं, यह सुनिश्चित करने के लिए जांचें कि इसमें केवल संख्यात्मक शब्द हैं।

यदि आप वास्तव में संख्यात्मक मूल्य का उपयोग करना चाहते हैं, तो उपयोग करें Integer.parseInt()या Double.parseDouble()जैसा कि दूसरों ने नीचे बताया है।


एक तरफ ध्यान दें के रूप में, यह आम तौर पर खराब व्यवहार का माना जाता है करने के लिए बूलियन मूल्यों की तुलना करने trueया false। बस का उपयोग करें if (condition)या if (!condition)


25
आप शायद एंकर जोड़ना चाहते हैं (जैसे ^[0-9]+$) अन्यथा abc123defएक नंबर माना जाएगा।
आईसीआर

10
मुझे नहीं लगता कि इसकी आवश्यकता है। matches()अगर यह शुरू से अंत तक पूरा मैच है और केवल तभी ही सही है।
चॉनिक प्रोजेक्ट

4
"^ -? \ d + \।? \ d * $" पूरे स्ट्रिंग की तुलना करेगा और केवल तभी मिलान करेगा यदि यह एक वैध संख्या (नकारात्मक और दशमलव शामिल) है। उदाहरण के लिए, यह 1, 10, 1.0, -1, -1.0 आदि से मेल खाएगा। यह "1." पर भी मेल खाएगा। लेकिन यह अक्सर वैसे भी पार्स किया जा सकता है।

16
कॉल करने की कोई जरूरत नहीं है && (text.length() > 2)। रेगेक्स पैटर्न में सब कुछ चेक किया जा सकता है:if (text.matches("[0-9]{3,}")
ctomek

संख्याओं के लिए अल्पविराम या बिंदुओं के बारे में क्या जो पूर्णांक नहीं हैं?
निबाना

20

आप Apache Commons से NumberUtil.isCreatable (स्ट्रिंग str) का भी उपयोग कर सकते हैं


4
मुझे नहीं लगता NumberUtil.isCreatable(String str)कि जो मूल प्रश्न पूछता है, उसके लिए उपयोग करना सही है। उदाहरण के लिए, NumberUtil.isCreatable( "09" )रिटर्न false, भले ही "09" केवल संख्याएँ हों
अब्दुल्ला

14

यह है कि मैं यह कैसे करेंगे:

if(text.matches("^[0-9]*$") && text.length() > 2){
    //...
}

$एक आंशिक मैच जैसे से बचने जाएगा; 1B


1
मुझे इस text.length() > 2भाग की आवश्यकता नहीं है , इसलिए मुझे यकीन है कि मेरे पास कम से कम एक संख्या है, ^[0-9]*$द्वारा प्रतिस्थापित किया ^[0-9]+$जाएगा।
YB कॉज

8

प्रदर्शन-वार parseIntऔर ऐसे अन्य समाधानों की तुलना में बहुत अधिक खराब हैं, क्योंकि कम से कम अपवाद से निपटने की आवश्यकता होती है।

मैंने jmh परीक्षण चलाए हैं और पाया है कि स्ट्रिंग का उपयोग करके स्ट्रिंग के charAtसाथ तुलना करना और स्ट्रिंग पर केवल अंकों का परीक्षण करना सबसे तेज़ तरीका है।

जेएमएच परीक्षण

टेस्ट Character.isDigitबनाम Pattern.matcher().matchesबनाम प्रदर्शन की तुलना Long.parseLongचार मूल्यों की जाँच करते हैं।

इन तरीकों से गैर-एससीआई तार और तार वाले +/- संकेतों के लिए अलग-अलग परिणाम उत्पन्न हो सकते हैं।

5 वार्मअप पुनरावृत्तियों और 5 परीक्षण पुनरावृत्तियों के साथ थ्रूपुट मोड में परीक्षण ( अधिक बेहतर है )।

परिणाम

ध्यान दें कि पहले परीक्षण भार parseLongकी तुलना में लगभग 100 गुना धीमा है isDigit

## Test load with 25% valid strings (75% strings contain non-digit symbols)

Benchmark       Mode  Cnt  Score   Error  Units
testIsDigit    thrpt    5  9.275 ± 2.348  ops/s
testPattern    thrpt    5  2.135 ± 0.697  ops/s
testParseLong  thrpt    5  0.166 ± 0.021  ops/s

## Test load with 50% valid strings (50% strings contain non-digit symbols)

Benchmark              Mode  Cnt  Score   Error  Units
testCharBetween       thrpt    5  16.773 ± 0.401  ops/s
testCharAtIsDigit     thrpt    5  8.917 ± 0.767  ops/s
testCharArrayIsDigit  thrpt    5  6.553 ± 0.425  ops/s
testPattern           thrpt    5  1.287 ± 0.057  ops/s
testIntStreamCodes    thrpt    5  0.966 ± 0.051  ops/s
testParseLong         thrpt    5  0.174 ± 0.013  ops/s
testParseInt          thrpt    5  0.078 ± 0.001  ops/s

परीक्षण सूट

@State(Scope.Benchmark)
public class StringIsNumberBenchmark {
    private static final long CYCLES = 1_000_000L;
    private static final String[] STRINGS = {"12345678901","98765432177","58745896328","35741596328", "123456789a1", "1a345678901", "1234567890 "};
    private static final Pattern PATTERN = Pattern.compile("\\d+");

    @Benchmark
    public void testPattern() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                b = PATTERN.matcher(s).matches();
            }
        }
    }

    @Benchmark
    public void testParseLong() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                try {
                    Long.parseLong(s);
                    b = true;
                } catch (NumberFormatException e) {
                    // no-op
                }
            }
        }
    }

    @Benchmark
    public void testCharArrayIsDigit() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                for (char c : s.toCharArray()) {
                    b = Character.isDigit(c);
                    if (!b) {
                        break;
                    }
                }
            }
        }
    }

    @Benchmark
    public void testCharAtIsDigit() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                for (int j = 0; j < s.length(); j++) {
                    b = Character.isDigit(s.charAt(j));
                    if (!b) {
                        break;
                    }
                }
            }
        }
    }

    @Benchmark
    public void testIntStreamCodes() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                b = s.chars().allMatch(c -> c > 47 && c < 58);
            }
        }
    }

    @Benchmark
    public void testCharBetween() {
        for (int i = 0; i < CYCLES; i++) {
            for (String s : STRINGS) {
                boolean b = false;
                for (int j = 0; j < s.length(); j++) {
                    char charr = s.charAt(j);
                    b = '0' <= charr && charr <= '9';
                    if (!b) {
                        break;
                    }
                }
            }
        }
    }
}

23 फरवरी, 2018 को अपडेट किया गया

  • दो और मामले जोड़ें - एक charAtअतिरिक्त सरणी बनाने के बजाय और IntStreamचार कोड का उपयोग करके
  • लूपेड टेस्ट मामलों के लिए गैर-अंक पाए जाने पर तत्काल ब्रेक जोड़ें
  • लूपेड परीक्षण मामलों के लिए खाली स्ट्रिंग के लिए गलत लौटें

23 फरवरी, 2018 को अपडेट किया गया

  • एक और परीक्षण मामला जोड़ें (सबसे तेज़!) जो स्ट्रीम का उपयोग किए बिना चार मूल्य की तुलना करता है

1
यदि आपCharArray के कोड को देखते हैं, तो यह एक वर्ण सरणी आवंटित कर रहा है और वर्णों की नकल कर रहा है (मुझे लगता है कि महंगा हो सकता है)। क्या होगा अगर आप केवल एक इंडेक्स और चारएट का उपयोग करके स्ट्रिंग को इटर्सेट करते हैं, तो क्या यह तेज होगा? यह भी दिलचस्प होगा कि यदि आप एंडी से अपने परीक्षणों में समाधान जोड़ सकते हैं: बूलियन isNum = text.chars ()। AllMatch (c -> c> = 48 && c <= 57)
Aldo Canepa

8

केवल स्ट्रिंग की जाँच करने के लिए कि इसमें केवल ALPHABETS शामिल है, निम्नलिखित कोड का उपयोग करें:

if (text.matches("[a-zA-Z]+"){
   // your operations
}

केवल स्ट्रिंग की जांच करने के लिए कि इसमें केवल NUMBER शामिल हैं, निम्नलिखित कोड का उपयोग करें:

if (text.matches("[0-9]+"){
   // your operations
}

आशा है कि यह किसी की मदद करेगा!


3

बूलियन isNum = text.chars ()। AllMatch (c -> c> = 48 && c <= 57)


1
जादू की संख्या को कम करने के लिए, आप इस प्रकार तुलना कर सकते हैं:boolean isNum = text.chars().allMatch(c -> c >= '0' && c <= '9')
Phe0nix

2

आप Regex.Match का उपयोग कर सकते हैं

if(text.matches("\\d*")&& text.length() > 2){
    System.out.println("number");
}

या आप उदाहरण के लिए जैसे बड़ी संख्या के लिए प्याज Integer.parseInt(String)या बेहतर का उपयोग कर सकते हैं Long.parseLong(String):

private boolean onlyContainsNumbers(String text) {
    try {
        Long.parseLong(text);
        return true;
    } catch (NumberFormatException ex) {
        return false;
    }
} 

और फिर के साथ परीक्षण:

if (onlyContainsNumbers(text) && text.length() > 2) {
    // do Stuff
}

.matches ("^ \\ d + $")
CrandellWS

2

नीचे रिग्क्स का उपयोग यह जांचने के लिए किया जा सकता है कि क्या एक स्ट्रिंग में केवल संख्या है या नहीं:

if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))

trueयदि स्ट्रिंग में गैर-संख्याएँ हैं, तो उपरोक्त दोनों स्थितियाँ वापस आ जाएँगी । ऑन false, स्ट्रिंग में केवल संख्याएँ होती हैं।


2

अपाचे कॉमन्स लैंग प्रदान करता है org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs), जो एक तर्क के रूप में लेता है Stringऔर जांचता है कि क्या यह विशुद्ध रूप से संख्यात्मक वर्णों (गैर-लैटिन लिपियों से संख्या सहित) में है। falseयदि कोई स्थान, माइनस, प्लस और दशमलव विभाजक जैसे अल्पविराम और बिंदु जैसे अक्षर हैं तो यह विधि वापस आती है ।

उस वर्ग की अन्य विधियां आगे के संख्यात्मक जांच की अनुमति देती हैं।


1
यह एक रेगेक्स की तुलना में बहुत तेज होना चाहिए; यहाँ एक कार्यान्वयन है: public static boolean isNumeric(String str) { if (str == null) { return false; } else { int sz = str.length(); for(int i = 0; i < sz; ++i) { if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } }
सिंह

1

Stringजावा (और इसके विपरीत) से नंबर प्राप्त करने के लिए बहुत सारी सुविधाएं हैं । आप अपने आप को उस जटिलता को दूर करने के लिए रेगेक्स भाग को छोड़ना चाह सकते हैं।

उदाहरण के लिए, आप कोशिश कर सकते हैं और देख सकते हैं कि Double.parseDouble(String s)आपके लिए क्या रिटर्न है। इसे फेंक देना चाहिए NumberFormatExceptionअगर यह स्ट्रिंग में एक उचित मूल्य नहीं पाता है। मैं इस तकनीक का सुझाव दूंगा क्योंकि आप वास्तव Stringमें एक संख्यात्मक प्रकार के रूप में प्रतिनिधित्व मूल्य का उपयोग कर सकते हैं ।


5
अपने इनपुट का परीक्षण करने के लिए एक अपवाद के रूप में अपवाद का उपयोग करना एक बुरा विचार हो सकता है, अपवाद एक बड़ा उपरि बनाता है।
आईर लुजोन

1
@OfirLuzon मैं मानता हूं कि अपवाद अपेक्षित मामलों को संभालने का एक शानदार तरीका नहीं है। हालाँकि मुझे लगता है कि यह बताना मुश्किल है कि क्या बिना अधिक संदर्भ के कोई प्रदर्शन हिट होगा।
स्यूडोरामबल

1

यहाँ मेरा कोड है, आशा है कि यह आपकी मदद करेगा!

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

    if (text.matches("[0-9]+") && text.length() > 2) {
        isDigit = true;
    }else {
        isDigit = false;
    }

    return isDigit;
}

0

यह कोड पहले से ही लिखा हुआ है। यदि आपको (अत्यंत) मामूली प्रदर्शन पर कोई आपत्ति नहीं है - जो शायद रेगेक्स मैच करने से भी बदतर नहीं है - तो Integer.parseInt () या Double.parseDouble () का उपयोग करें । यदि कोई स्ट्रिंग केवल संख्या है (या उचित रूप में एक संख्या है), तो यह आपको तुरंत बता देगा । यदि आपको संख्याओं के लंबे तारों को संभालने की आवश्यकता है, तो BigInteger और BigDecimal दोनों खेल निर्माता जो स्ट्रिंग्स स्वीकार करते हैं। यदि आप इसे एक गैर-संख्या (अभिन्न या दशमलव, जिसे आप चुनते हैं, निश्चित रूप से चुनते हैं) के आधार पर पास करने का प्रयास करते हैं, तो इनमें से कोई भी NumberFormatException को फेंक देगा । वैकल्पिक रूप से, अपनी आवश्यकताओं के आधार पर, स्ट्रिंग में वर्णों को पुनरावृत्त करें और Character.isDigit () की जांच करेंऔर / या Character.isLetter ()


0
import java.util.*;

class Class1 {
    public static void main(String[] argh) {
        boolean ans = CheckNumbers("123");
        if (ans == true) {
            System.out.println("String contains numbers only");
        } else {
            System.out.println("String contains other values as well");

        }
    }


    public static boolean CheckNumbers(String input) {
        for (int ctr = 0; ctr < input.length(); ctr++) {
            if ("1234567890".contains(Character.valueOf(input.charAt(ctr)).toString())) {
                continue;
            } else {
                return false;
            }
        }
        return true;
    }
}

0
Character first_letter_or_number = query.charAt(0);
                //------------------------------------------------------------------------------
                if (Character.isDigit())
                {

                }
                else if (Character.isLetter())
                {

                }

0

कार्य परीक्षण उदाहरण

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

public class PaserNo {

    public static void main(String args[]) {

        String text = "gg";

        if (!StringUtils.isBlank(text)) {
            if (stringContainsNumber(text)) {
                int no=Integer.parseInt(text.trim());
                System.out.println("inside"+no);

            } else {
                System.out.println("Outside");
            }
        }
        System.out.println("Done");
    }

    public static boolean stringContainsNumber(String s) {
        Pattern p = Pattern.compile("[0-9]");
        Matcher m = p.matcher(s);
        return m.find();
    }
}

फिर भी आपका कोड "1 ए" आदि से टूट सकता है, इसलिए आपको अपवाद की जांच करने की आवश्यकता है

if (!StringUtils.isBlank(studentNbr)) {
                try{
                    if (isStringContainsNumber(studentNbr)){
                    _account.setStudentNbr(Integer.parseInt(studentNbr.trim()));
                }
                }catch(Exception e){
                    e.printStackTrace();
                    logger.info("Exception during parse studentNbr"+e.getMessage());
                }
            }

नं की जाँच के लिए विधि स्ट्रिंग है या नहीं

private boolean isStringContainsNumber(String s) {
        Pattern p = Pattern.compile("[0-9]");
        Matcher m = p.matcher(s);
        return m.find();
    }

0

इस तरह के एक विशिष्ट परिदृश्य में किसी भी अपवाद को फेंकना / संभालना शामिल करना एक बुरा अभ्यास है।

इसलिए एक parseInt () अच्छा नहीं है, लेकिन एक regex इस के लिए एक सुरुचिपूर्ण समाधान है, लेकिन निम्नलिखित की देखभाल:
-fractions
-नकारात्मक संख्या
-decimal विभाजक contries में अंतर हो सकता है ( '।' जैसे ',' या)
कभी कभी, यह एक तथाकथित हजार विभाजक की अनुमति है, जैसे एक अंतरिक्ष या अल्पविराम जैसे 12,324,1000.355

अपने आवेदन में सभी आवश्यक मामलों को संभालने के लिए आपको सावधान रहना होगा, लेकिन यह regex ठेठ परिदृश्यों (सकारात्मक / नकारात्मक और आंशिक, एक डॉट द्वारा अलग) को कवर करता है: ^ [- +]? \ D *।? \ D + $ के
लिए परीक्षण, मैं regexr.com सुझाता हूं


0

एडम बोड्रोगी का थोड़ा संशोधित संस्करण:

public class NumericStr {


public static void main(String[] args) {
    System.out.println("Matches: "+NumericStr.isNumeric("20"));         // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("20,00"));          // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("30.01"));          // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("30,000.01"));          // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("-2980"));          // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("$20"));            // Should be true
    System.out.println("Matches: "+NumericStr.isNumeric("jdl"));            // Should be false
    System.out.println("Matches: "+NumericStr.isNumeric("2lk0"));           // Should be false
}

public static boolean isNumeric(String stringVal) {
    if (stringVal.matches("^[\\$]?[-+]?[\\d\\.,]*[\\.,]?\\d+$")) {
        return true;
    }

    return false;
}
}

आज इसका इस्तेमाल करना था इसलिए मैंने अपने संशोधन पोस्ट किए। मुद्रा, हजारों अल्पविराम या अवधि संकेतन, और कुछ सत्यापन शामिल हैं। अन्य मुद्रा संकेतन (यूरो, सेंट) शामिल नहीं हैं, सत्यापन कॉमा हर तीसरे अंक हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.