Java字符串—查看字符串是否只包含数字而不包含字母

我在应用程序中加载了一个字符串,它可以从数字变成字母等等。我有一个简单的if语句,看看它是否包含字母或数字,但是,有些东西不太正确。下面是一个片段。

String text = "abc";
String number;


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

虽然text变量确实包含字母,但条件返回为true。为了处理number = text;&&&&应该eval为必须为true的两个条件

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

< em >解决方案:< / em >

我能够通过使用以下代码来解决这个问题,该代码由对这个问题的评论提供。所有其他帖子也是有效的!

我使用的有效方法来自第一条评论。虽然提供的所有示例代码似乎也是有效的!

String text = "abc";
String number;


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

在Java中有很多从__abc0中获取数字的工具(反之亦然)。您可能希望跳过正则表达式部分,以避免其复杂化。

例如,你可以尝试看看Double.parseDouble(String s)为你返回什么。如果在字符串中没有找到合适的值,它应该抛出NumberFormatException。我建议使用这种技术,因为您实际上可以将String表示的值作为数字类型使用。

如果要将数字作为文本处理,则更改:

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

:

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

不是检查字符串是否包含字母字符,而是检查它是否包含只有数字。

如果你真的想使用数值,使用Integer.parseInt()Double.parseDouble(),正如其他人在下面解释的那样。


作为旁注,将布尔值与truefalse进行比较通常被认为是不好的做法。只要使用if (condition)if (!condition)即可。

这段代码已经写好了。如果你不介意(极其)微小的性能损失——这可能并不比正则表达式匹配更糟糕——使用Integer.parseInt ()Double.parseDouble ()。这将立即告诉你String是否只有数字(或是一个数字,视情况而定)。如果你需要处理较长的数字字符串,BigIntegerBigDecimal构造函数都接受字符串。如果你试图传递一个非数字(当然,基于你选择的整数或小数),其中任何一个都会抛出NumberFormatException。或者,根据您的要求,只需迭代String中的字符并检查Character.isDigit ()和/或Character.isLetter ()

你也可以从Apache Commons中使用NumberUtil。isCreatable (String str)

你可以使用正则表达式。匹配

if(text.matches("\\d*")&& text.length() > 2){
System.out.println("number");
}
或者你可以使用像Integer.parseInt(String)或更好的Long.parseLong(String)这样的onversions来表示更大的数字 例如:

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

然后用:

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

我是这样做的:

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

$将避免部分匹配,例如;1B

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;
}
}

boolean isNum = text.chars()。allMatch(c -> c >= 48 &&C <= 57)

下面的正则表达式可以用来检查字符串是否只有数字:

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

如果String包含非数字,上述两种情况都将返回true。在false中,string只有数字。

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


}
else if (Character.isLetter())
{


}

Apache Commons Lang提供了org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs),它接受String作为参数,并检查它是否由纯数字字符组成(包括来自非拉丁脚本的数字)。如果存在空格、减号、加号等字符,以及逗号和点等小数分隔符,则该方法返回false

该类的其他方法允许进一步的数值检查。

在性能方面,parseInt之类的方法比其他解决方案要差得多,因为至少需要异常处理。

我已经运行jmh测试,并发现使用charAt迭代字符串,并将字符与边界字符进行比较是测试字符串是否只包含数字的最快方法。

JMH测试

测试比较Character.isDigitPattern.matcher().matchesLong.parseLong和检查char值的性能。

对于非ascii字符串和包含+/-号的字符串,这些方法可以产生不同的结果。

测试以吞吐量模式(越大越好)运行,有5个预热迭代和5个测试迭代。

结果

注意,在第一次测试加载时,parseLong几乎比isDigit慢100倍。

## 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;
}
}
}
}
}
}

2018年2月23日更新

  • 再添加两种情况——一种使用charAt而不是创建额外的数组,另一种使用char代码的IntStream
  • 如果在循环测试用例中发现非数字,则添加立即中断
  • 对于循环测试用例,空字符串返回false

2018年2月23日更新

  • 再添加一个不使用流比较char值的测试用例(最快的!)

为了检查字符串是否只包含字母,请使用以下代码:

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

为了检查字符串是否只包含NUMBER,请使用以下代码:

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

希望这对一些人有所帮助!

工作测试示例

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();
}
}

你的代码仍然可以被“1a”等打破,所以你需要检查异常

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());
}
}

检查no是否是字符串的方法

private boolean isStringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
在这样的典型场景中涉及任何异常抛出/处理都是一种糟糕的实践。

因此parseInt()不是很好,但regex是一个优雅的解决方案,但要注意以下几点 分数
消极的数字
-十进制分隔符可能因国家而异(例如:',' or '.')
-有时允许使用所谓的千位分隔符,如空格或逗号,例如12324,1000.355

要处理应用程序中所有必要的情况,你必须小心,但这个正则表达式涵盖了典型的场景(正/负和分数,由一个点分隔):^[-+]?\d*.?美元\ d +
对于测试,我推荐regexr.com

这是我的代码,希望对你有所帮助!

 public boolean isDigitOnly(String text){


boolean isDigit = false;


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


return isDigit;
}

亚当·博德罗吉的略有修改版本:

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;
}
}

今天不得不使用这个,所以刚刚发布了我的修改。包括货币、千位逗号或句号符号,以及一些验证。不包括其他货币符号(欧元、分),验证逗号为每三位数。

public class Test{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str;
boolean status=false;
System.out.println("Enter the String : ");
str = sc.nextLine();
    

char ch[] = str.toCharArray();
    

for(int i=0;i<ch.length;i++) {
if(ch[i]=='1'||ch[i]=='2'||ch[i]=='3'||ch[i]=='4'||ch[i]=='5'||ch[i]=='6'||ch[i]=='7'||ch[i]=='8'||ch[i]=='9'||ch[i]=='0') {
ch[i] = 0;
}
}
    

for(int i=0;i<ch.length;i++) {
if(ch[i] != 0) {
System.out.println("Mixture of letters and Digits");
status = false;
break;
}
else
status = true;
}
    

if(status == true){
System.out.println("Only Digits are present");
}
}

这是一个样品。根据需要,只查找字符串和过程形式中的数字。

text.replaceAll("\\d(?!$)", "$0 ");

更多信息请查看谷歌文档 https://developer.android.com/reference/java/util/regex/Pattern你可以使用模式

使用Java 8流和lambda的解决方案

String data = "12345";
boolean isOnlyNumbers = data.chars().allMatch(Character::isDigit);
StringUtils.isNumeric("1234")

这很好。

boolean flag = false;
System.out.print("Enter String : ");
String str = new Scanner(System.in).next();


for (int i = 0; i < str.length(); i++)
{
if (str.length() <= 0)
{
System.out.println("String length Can't be zero.");
return;
}
char ch = str.charAt(i);
int c = ch;
if (c >= 48 && c <= 58)
{
flag = true;
} else
{
flag = false;
break;
}
}
if (flag)
{
System.out.println("input [" + str + "] contains number only.");
} else
System.out.println("input [" + str + "] have some non string values in it.");

你也可以使用[a-zA-Z]{2,}

其中[a-zA-Z]只检查字母,而{2,}检查长度,应该大于2