235

我在整个应用程序中加载了一个字符串,它从数字变为字母等。我有一个简单的if语句来查看它是否包含字母或数字,但是有些东西不能正常工作。这是一个片段。

String text = "abc"; 
String number; 

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

尽管text变量确实包含字母,但条件返回为true。和&&应该评估两个条件必须是true为了处理number = text;

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

解决方案:

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

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

String text = "abc"; 
String number; 

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

21 回答 21

401

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

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

至:

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

与其检查字符串是否不包含字母字符,不如检查以确保它包含数字。

如果您确实想使用数值,请使用Integer.parseInt()Double.parseDouble()其他人在下面解释。


true附带说明一下,将布尔值与or进行比较通常被认为是不好的做法false。只需使用if (condition)or if (!condition)

于 2012-05-13T22:14:20.360 回答
21

您还可以使用来自 Apache Commons 的NumberUtil.isCreatable(String str)

于 2015-01-23T10:03:47.030 回答
18

我会这样做:

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

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

于 2016-09-16T12:05:54.310 回答
13

为了简单地检查它只包含 ALPHABETS 的字符串,请使用以下代码:

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

为了简单地检查它只包含 NUMBER 的字符串,请使用以下代码:

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

希望这对某人有帮助!

于 2018-05-01T08:36:45.873 回答
12

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

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

JMH 测试

测试比较了Character.isDigitvs Pattern.matcher().matchesvs Long.parseLongvs 检查 char 值的性能。

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

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

结果

请注意,这parseLongisDigit第一次测试加载慢了近 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而不是创建额外的数组,另一种使用IntStreamchar 代码
  • 如果为循环测试用例找到非数字,则添加立即中断
  • 为循环测试用例的空字符串返回 false

更新于 2018 年 2 月 23 日

  • 再添加一个测试用例(最快的!),在不使用流的情况下比较 char 值
于 2018-02-20T10:26:49.900 回答
7

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

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

于 2018-02-01T12:42:41.087 回答
4

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

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

true如果 String 包含非数字,则上述两个条件都将返回。上false,字符串只有数字。

于 2017-04-16T23:51:32.600 回答
4

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

于 2017-01-27T22:33:56.190 回答
3

您可以使用 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
}
于 2016-09-16T09:53:25.297 回答
2

在 Java中有很多工具可以从Strings 获取数字(反之亦然)。您可能想跳过正则表达式部分,以免造成复杂性。

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

于 2012-05-13T22:13:37.113 回答
2

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

String data = "12345";
boolean isOnlyNumbers = data.chars().allMatch(Character::isDigit);
于 2021-12-24T14:07:11.963 回答
2

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

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

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

    return isDigit;
}
于 2018-09-27T11:56:42.677 回答
2
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;
    }
}
于 2016-12-01T08:03:48.773 回答
1

这是一个示例。根据需要仅查找字符串和进程格式中的数字。

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

有关更多信息,请查看谷歌文档 https://developer.android.com/reference/java/util/regex/Pattern在哪里可以使用Pattern

于 2021-01-22T19:24:53.337 回答
1
StringUtils.isNumeric("1234")

这很好用。

于 2022-02-15T05:16:22.993 回答
0

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

于 2012-05-13T22:15:28.520 回答
0
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");
    }
}

}

于 2020-10-06T06:22:41.220 回答
0

Adam Bodrogi 稍作修改的版本:

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

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

于 2020-01-21T15:53:24.993 回答
0

在这种典型场景中涉及任何异常抛出/处理是一种不好的做法。

因此 parseInt() 不是很好,但正则表达式是一个优雅的解决方案,但请注意以下事项:
-fractions
-负数 -
小数分隔符可能在 contries 中有所不同(例如','或'.')
-有时允许有一个所谓的千位分隔符,例如空格或逗号,例如 12,324,1000.355

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

于 2018-09-02T20:05:25.133 回答
0
Character first_letter_or_number = query.charAt(0);
                //------------------------------------------------------------------------------
                if (Character.isDigit())
                {

                }
                else if (Character.isLetter())
                {

                }
于 2017-12-29T01:07:51.357 回答
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();
    }
}

您的代码仍然可以被“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();
    }
于 2018-05-17T20:58:46.330 回答