La chiamata Character.isLetter(c)
ritorna true
se il carattere è una lettera. Ma c'è un modo per scoprire rapidamente se a String
contiene solo i caratteri di base di ASCII?
La chiamata Character.isLetter(c)
ritorna true
se il carattere è una lettera. Ma c'è un modo per scoprire rapidamente se a String
contiene solo i caratteri di base di ASCII?
Risposte:
Da Guava 19.0 in poi, puoi usare:
boolean isAscii = CharMatcher.ascii().matchesAllOf(someString);
Questo utilizza il matchesAllOf(someString)
metodo che si basa sul metodo factory ascii()
piuttosto che sul ASCII
singleton ormai deprecato .
Qui ASCII include tutti i caratteri ASCII inclusi i caratteri non stampabili inferiori a 0x20
(spazio) come tabulazioni, line-feed / return ma anche BEL
con codice 0x07
e DEL
con codice 0x7F
.
Questo codice utilizza in modo non corretto i caratteri anziché i punti di codice, anche se i punti di codice sono indicati nei commenti delle versioni precedenti. Fortunatamente, i caratteri richiesti per creare un punto di codice con un valore pari U+010000
o superiore a utilizzano due caratteri surrogati con un valore al di fuori dell'intervallo ASCII. Quindi il metodo riesce ancora a testare ASCII, anche per stringhe contenenti emoji.
Per le versioni precedenti di Guava senza il ascii()
metodo puoi scrivere:
boolean isAscii = CharMatcher.ASCII.matchesAllOf(someString);
CharMatcher.ASCII
è deprecato ora e sta per essere rimosso a giugno 2018.
Puoi farlo con 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
*/
}
}
StandardCharsets.US_ASCII
posto di Charset.forName("US-ASCII")
.
StandardCharsets
? Potrei pubblicare un'altra risposta, ma preferisco correggere questa risposta molto apprezzata.
Ecco un altro modo che non dipende da una libreria ma utilizza un'espressione regolare.
Puoi usare questa singola riga:
text.matches("\\A\\p{ASCII}*\\z")
Intero programma di esempio:
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"));
}
}
\P{Print}
e \P{Graph}
+ una descrizione? Perché hai bisogno di \A
e \z
?
Scorri la stringa e assicurati che tutti i caratteri abbiano un valore inferiore a 128.
Le stringhe Java sono concettualmente codificate come UTF-16. In UTF-16, il set di caratteri ASCII è codificato come i valori 0-127 e la codifica per qualsiasi carattere non ASCII (che può essere costituito da più di un carattere Java) è garantito per non includere i numeri 0-127
str.chars().allMatch(c -> c < 128)
c >= 0x20 && c < 0x7F
poiché i primi 32 valori della codifica a 7 bit sono caratteri di controllo e il valore finale (0x7F) è DEL
.
Oppure copia il codice dalla classe 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;
}
return false
invece di utilizzare isASCII = false
e break
.
commons-lang3 di Apache contiene preziosi metodi di utilità / convenienza per tutti i tipi di "problemi", incluso questo.
System.out.println(StringUtils.isAsciiPrintable("!@£$%^&!@£$%^"));
prova questo:
for (char c: string.toCharArray()){
if (((int)c)>127){
return false;
}
}
return true;
Scorri la stringa e usa charAt () per ottenere il carattere. Quindi trattalo come un int e verifica se ha un valore Unicode (un superset di ASCII) che ti piace.
Rompi al primo che non ti piace.
private static boolean isASCII(String s)
{
for (int i = 0; i < s.length(); i++)
if (s.charAt(i) > 127)
return false;
return true;
}
charAt
restituisce a char
. Puoi testare direttamente se un tipo char
è maggiore di un int senza prima convertirlo in un int o il tuo test esegue automaticamente la copertura? Forse puoi e forse lo fa? Sono andato avanti e convertito questo per un int in questo modo: if ((int)s.charAt(i) > 127)
. Non sono sicuro che i miei risultati siano diversi, ma mi sento meglio a lasciarlo correre. Vedremo: - \
Era possibile. Bel problema.
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;
}
}
Questo restituirà true se String contiene solo caratteri ASCII e false quando non lo contiene
Charset.forName("US-ASCII").newEncoder().canEncode(str)
Se vuoi rimuovere non ASCII, ecco lo snippet:
if(!Charset.forName("US-ASCII").newEncoder().canEncode(str)) {
str = str.replaceAll("[^\\p{ASCII}]", "");
}
//return is uppercase or lowercase
public boolean isASCIILetter(char c) {
return (c > 64 && c < 91) || (c > 96 && c < 123);
}