अगर स्ट्रिंग में केवल ASCII है तो कैसे जांचें?


120

यदि वर्ण एक अक्षर है तो कॉल Character.isLetter(c)वापस आ trueजाता है। लेकिन क्या कोई रास्ता जल्दी से पता चल सकता है कि क्या Stringकेवल ASCII के आधार वर्ण हैं?

जवाबों:


128

से अमरूद 19.0 आगे, आप उपयोग कर सकते हैं:

boolean isAscii = CharMatcher.ascii().matchesAllOf(someString);

यह उस matchesAllOf(someString)विधि का उपयोग करता है जो ascii()अब पदावनत ASCIIसिंगलटन के बजाय फैक्ट्री विधि पर निर्भर करता है ।

यहाँ ASCII में सभी ASCII वर्ण शामिल हैं , जिनमें गैर-मुद्रण योग्य वर्ण 0x20(स्पेस) से कम हैं जैसे कि टैब, लाइन-फीड / रिटर्न लेकिन BELकोड के साथ 0x07और कोड के साथ भी ।DEL0x7F

यह कोड कोड बिंदुओं के बजाय वर्णों का गलत उपयोग करता है, भले ही कोड बिंदुओं को पहले के संस्करणों की टिप्पणियों में दर्शाया गया हो। सौभाग्य से, U+010000ASCII श्रेणी के बाहर के मान के साथ या उसके ऊपर दो मान वाले वर्णों का उपयोग करके कोड बिंदु बनाने के लिए आवश्यक वर्णों का उपयोग किया जाता है। तो विधि अभी भी ASCII के लिए परीक्षण में सफल होती है, यहां तक ​​कि इमोजी वाले तार के लिए भी।

ascii()आपके द्वारा लिखे जा सकने वाले तरीके के पहले के अमरूद संस्करणों के लिए :

boolean isAscii = CharMatcher.ASCII.matchesAllOf(someString);

31
+1 हालांकि यह अच्छा है यदि आपको किसी अन्य तृतीय-पक्ष लाइब्रेरी की आवश्यकता नहीं है, तो कॉलिन का उत्तर बहुत छोटा है और बहुत अधिक पठनीय है। तृतीय-पक्ष लाइब्रेरी का सुझाव देना पूरी तरह से ठीक है और इसे नकारात्मक वोट से दंडित नहीं किया जाना चाहिए।
जेसपर

1
मुझे यह भी इंगित करना चाहिए कि चारमैचर्स वास्तव में अविश्वसनीय रूप से शक्तिशाली हैं और इससे अधिक वाया कर सकते हैं। इसके अलावा ASCII के अलावा कई और पूर्वनिर्धारित CharMatchers हैं, और कस्टम बनाने के लिए महान कारखाने के तरीके।
कॉलिन डी

7
CharMatcher.ASCIIअब पदावनत किया गया है और के बारे में जून 2018 में निकालें होने के लिए
thisarattr

108

आप इसे java.nio.charset.Charset से कर सकते हैं ।

import java.nio.charset.Charset;

public class StringUtils {

  public static boolean isPureAscii(String v) {
    return Charset.forName("US-ASCII").newEncoder().canEncode(v);
    // or "ISO-8859-1" for ISO Latin 1
    // or StandardCharsets.US_ASCII with JDK1.7+
  }

  public static void main (String args[])
    throws Exception {

     String test = "Réal";
     System.out.println(test + " isPureAscii() : " + StringUtils.isPureAscii(test));
     test = "Real";
     System.out.println(test + " isPureAscii() : " + StringUtils.isPureAscii(test));

     /*
      * output :
      *   Réal isPureAscii() : false
      *   Real isPureAscii() : true
      */
  }
}

स्ट्रिंग में गैर-ASCII वर्ण का पता लगाएं


10
मुझे नहीं लगता कि डॉक्स के अनुसार चार्सेटएन्कोडर को स्थिर बनाना एक अच्छा विचार है "इस वर्ग के उदाहरण कई समवर्ती धागे द्वारा उपयोग के लिए सुरक्षित नहीं हैं।"
pm_labs

@paul_sns, आप सही हैं CharsetEncoder थ्रेड-सुरक्षित नहीं है (लेकिन Charset है) इसलिए इसे स्थिर बनाने के लिए यह एक अच्छा विचार नहीं है।
RealHowTo

11
जावा 1.7 या अधिक के साथ एक के StandardCharsets.US_ASCIIबजाय का उपयोग कर सकते हैं Charset.forName("US-ASCII")
जूलियन लेटनर

@RealHowTo सही समाधान के लिए टिप्पणियों पर भरोसा नहीं करना चाहिए, इस मुद्दे को ठीक करने के लिए देखभाल करना चाहिए और शायद ऑनलाइन विधि का उपयोग करना चाहिए StandardCharsets? मैं एक और उत्तर पोस्ट कर सकता था, लेकिन मैं इस अत्यधिक प्रशंसित उत्तर को ठीक करूंगा।
मार्टन बोडेवेस

77

यहां एक और तरीका है जो एक पुस्तकालय पर निर्भर नहीं करता है, लेकिन एक रेगेक्स का उपयोग करता है।

आप इस एकल पंक्ति का उपयोग कर सकते हैं:

text.matches("\\A\\p{ASCII}*\\z")

संपूर्ण उदाहरण कार्यक्रम:

public class Main {
    public static void main(String[] args) {
        char nonAscii = 0x00FF;
        String asciiText = "Hello";
        String nonAsciiText = "Buy: " + nonAscii;
        System.out.println(asciiText.matches("\\A\\p{ASCII}*\\z"));
        System.out.println(nonAsciiText.matches("\\A\\p{ASCII}*\\z"));
    }
}

15
\\ A - इनपुट की शुरुआत ... \\ p {ASCII} * - कोई भी ASCII वर्ण किसी भी समय ... \\ z - इनपुट का अंत
Arne Deutsch

@ArneDeutsch क्या आपको बुरा लगता है अगर मैं उत्तर को बेहतर बनाता हूं \P{Print}और \P{Graph}एक विवरण के संदर्भ और + शामिल करता हूं ? आप की जरूरत क्यों है \Aऔर \z?
Maarten Bodewes

वह रेगेक्स क्या है? मुझे पता है कि $ स्ट्रिंग का अंत है, ^ शुरू है, कभी भी \\ A \\ p \\ z के बारे में नहीं सुना है, क्या आप कृपया javadoc का संदर्भ संलग्न कर सकते हैं?
deathangel908

@ deathangel908 \ A इनपुट की शुरुआत है। \ z इनपुट का अंत है। ^ और $ MULTILINE मोड में अलग-अलग व्यवहार करते हैं, और DOTALL \ A और \ z के व्यवहार में परिवर्तन करते हैं। देखें stackoverflow.com/a/3652402/1003157
रेमंड Naseef

58

स्ट्रिंग के माध्यम से Iterate करें और सुनिश्चित करें कि सभी वर्णों का मान 128 से कम है।

जावा स्ट्रिंग्स को UTF-16 के रूप में अवधारणात्मक रूप से एन्कोड किया गया है। UTF-16 में, ASCII वर्ण सेट मान 0 - 127 के रूप में एन्कोड किया गया है और किसी भी गैर ASCII वर्ण के लिए एन्कोडिंग (जिसमें एक से अधिक जावा चार शामिल हो सकते हैं) को 0 - 127 नंबर शामिल नहीं करने की गारंटी है


27
जावा 1.8 के साथ आप कर सकते हैं:str.chars().allMatch(c -> c < 128)
जूलियन लेटनर

7
यदि आप मुद्रण योग्य वर्ण चाहते हैं, तो आप c >= 0x20 && c < 0x7F7 बिट एन्कोडिंग के पहले 32 मानों को नियंत्रित करना चाहते हैं और अंतिम मान (0x7F) है DEL
मार्टन बोडेवेस

15

या आप IDN क्लास से कोड कॉपी करते हैं ।

// to check if a string only contains US-ASCII code point
//
private static boolean isAllASCII(String input) {
    boolean isASCII = true;
    for (int i = 0; i < input.length(); i++) {
        int c = input.charAt(i);
        if (c > 0x7F) {
            isASCII = false;
            break;
        }
    }
    return isASCII;
}

1
यह भी 2-char-यूनिकोड के साथ काम करता है क्योंकि 1-char है> = U + D800
k3b

लेकिन ध्यान दें कि इसमें ASCII में गैर-मुद्रण योग्य वर्ण शामिल हैं (जो सही है, लेकिन इसकी उम्मीद नहीं की जा सकती है)। यह निश्चित रूप से उपयोग return falseकरने के बजाय सीधे उपयोग करना संभव है isASCII = falseऔर break
मैर्टन बोडेवेस

यह Oracle JDK का कोड है। नकल कानूनी मुद्दों का कारण हो सकता है।
Arne Deutsch

11

Apache से commons-lang3 में इस एक सहित सभी प्रकार की 'समस्याओं' के लिए मूल्यवान उपयोगिता / सुविधा विधियाँ शामिल हैं।

System.out.println(StringUtils.isAsciiPrintable("!@£$%^&!@£$%^"));

1
यदि स्ट्रिंग या टैब फ़ीड वर्ण (\ t \ r \ n) सम्‍मिलित है, तो यह ज्ञात रखें कि isAsciiPrintable गलत है।
तंपनहेज़

@TampaHaze thats क्योंकि आंतरिक रूप से, हर चरित्र मूल्य के लिए इसकी जाँच 32 से 127 के बीच होना चाहिए। मुझे लगता है कि गलत है। हमें ० से १२ should तक जांच करनी चाहिए
उपचारात्मक

1
@ अथेलाप्रशांत यदि विधि नाम isAscii है तो मैं आपसे सहमत हूँ। लेकिन नाम isAsciiPrintable होने का अर्थ है कि वे जानबूझकर 0 से 31 के वर्णों को छोड़ सकते हैं।
ताम्पा हेज़

4

इसे इस्तेमाल करे:

for (char c: string.toCharArray()){
  if (((int)c)>127){
    return false;
  } 
}
return true;

"यह कोशिश करो" हमेशा एक नीचा हो जाता है। यह क्या करता है ? क्या शामिल है और क्या नहीं है? नीचे उतरना होगा क्योंकि आप स्मृति में आकार को दोगुना करते हैं, वैसे भी।
मार्टन बॉड्यूज

1

स्ट्रिंग के माध्यम से Iterate करें, और char पाने के लिए charAt () का उपयोग करें। फिर इसे एक इंट के रूप में मानें, और देखें कि क्या इसका यूनिकोड मान (ASCII का सुपरसेट) है जो आपको पसंद है।

पहली बार में आपको पसंद नहीं है।


1
private static boolean isASCII(String s) 
{
    for (int i = 0; i < s.length(); i++) 
        if (s.charAt(i) > 127) 
            return false;
    return true;
}

कोड केवल उत्तर दें, कृपया इंगित करें कि यह क्या करता है, अर्थात इसमें गैर-मुद्रण योग्य वर्ण और एक अपरिभाषित वर्ण (0x7F) शामिल हैं यदि आप यह चेक करते हैं।
Maarten Bodewes

ब्याज के किसी भी पात्र को खोजने में मेरे लंबे समय से चल रहे कार्यक्रम के बाद यह मेरे पास हो सकता है। charAtएक रिटर्न char। क्या आप सीधे परीक्षण कर सकते हैं यदि कोई प्रकार charएक इंट से अधिक एक इंट से पहले बिना परिवर्तित होता है, या आपका परीक्षण स्वचालित रूप से सहवास करता है? शायद आप कर सकते हैं और शायद यह करता है? मैं आगे बढ़ा और इसे एक इंट में बदल दिया जैसे if ((int)s.charAt(i) > 127):। सुनिश्चित नहीं हैं कि मेरे परिणाम किसी भी भिन्न हैं, लेकिन मैं इसे चलाने देना बेहतर समझता हूं। हम देख सकते हैं: - \
harperville

0

यह संभव था। बहुत समस्या है।

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

public class EncodingTest {

    static CharsetEncoder asciiEncoder = Charset.forName("US-ASCII")
            .newEncoder();

    public static void main(String[] args) {

        String testStr = "¤EÀsÆW°ê»Ú®i¶T¤¤¤ß3¼Ó®i¶TÆU2~~KITEC 3/F Rotunda 2";
        String[] strArr = testStr.split("~~", 2);
        int count = 0;
        boolean encodeFlag = false;

        do {
            encodeFlag = asciiEncoderTest(strArr[count]);
            System.out.println(encodeFlag);
            count++;
        } while (count < strArr.length);
    }

    public static boolean asciiEncoderTest(String test) {
        boolean encodeFlag = false;
        try {
            encodeFlag = asciiEncoder.canEncode(new String(test
                    .getBytes("ISO8859_1"), "BIG5"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodeFlag;
    }
}

0

यह सच हो जाएगा अगर स्ट्रिंग में केवल ASCII वर्ण हैं और जब यह नहीं है तो गलत है

Charset.forName("US-ASCII").newEncoder().canEncode(str)

यदि आप गैर ASCII हटाना चाहते हैं, तो यहाँ स्निपेट है:

if(!Charset.forName("US-ASCII").newEncoder().canEncode(str)) {
                        str = str.replaceAll("[^\\p{ASCII}]", "");
                    }

-2
//return is uppercase or lowercase
public boolean isASCIILetter(char c) {
  return (c > 64 && c < 91) || (c > 96 && c < 123);
}

एक कोड केवल 4 जादूगरों के साथ उत्तर देता है, और कोई स्पष्टीकरण नहीं देता है कि वह क्या करता है । कृपया समायोजित करें।
Maarten Bodewes
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.