Java字符串-查看字符串是否仅包含数字而不包含字母


194

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

String text = "abc"; 
String number; 

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

尽管text变量确实包含字母,但条件返回为true。的和&&应该EVAL为具有既条件true以处理所述number = text;

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

解:

我可以通过使用以下有关问题注释的代码来解决此问题。其他所有帖子也有效!

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

String text = "abc"; 
String number; 

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

5
contains不使用正则表达式作为输入。使用任一方法matches("\\d{2,}")或尝试使用PatternMatcher
Guillaume Polet,2012年

字符串可以有十进制值还是只有整数值?

3
为什么要检查text.length()> 2?什么原因?
热情的Code

1
@RedHatcc Pattern.matches("[a-zA-Z]+", text) == false可以简化为!Pattern.matches("[a-zA-Z]+", text)
SARose

2
使用java流API boolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x));形式Max Malysh发布。
Yash

Answers:


353

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

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将被视为数字。
ICR

10
我认为这不是必需的。matches()当且仅当从头到尾完全匹配时才返回true。
Chthonic Project 2013年

4
“ ^-?\ d + \。?\ d * $”将比较整个字符串,并且只有在它是有效数字(包括负数和小数)的情况下才匹配。例如,它将匹配1、10、1.0,-1,-1.0等。它还将匹配“ 1”。但这通常可以被解析。

16
无需致电&& (text.length() > 2)。一切都可以用正则表达式模式检查:if (text.matches("[0-9]{3,}")
ctomek

非整数的逗号或点怎么办?
nibbana


14

这就是我要做的:

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

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


1
我不需要这个text.length() > 2部分,因此我只替换^[0-9]*$^[0-9]+$以确保我至少有一个数字。
YB原因

8

从性能角度parseInt来看,这种方法比其他解决方案要差得多,因为至少需要进行异常处理。

我已经运行了jmh测试,发现使用charAt并比较char和边界char 遍历String 是测试string是否仅包含数字的最快方法。

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而不是创建额外的数组,另一种使用IntStream字符代码
  • 如果发现循环测试用例没有数字,则添加立即中断
  • 对于循环测试用例的空字符串返回false

于2018年2月23日更新

  • 添加另一个测试用例(最快!),用于比较char值而不使用流

1
如果您查看toCharArray的代码,它将分配一个char数组并复制这些chars(我认为那可能会很昂贵)。如果仅使用索引和charAt迭代字符串,会更快吗?如果您可以将Andy的解决方案添加到测试中,也将很有趣:boolean isNum = text.chars()。allMatch(c-> c> = 48 && c <= 57)
Aldo Canepa

8

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

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

或者,您可以使用onversions 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如果String包含非数字,则以上两个条件都将返回。在上false,字符串只有数字。


2

Apache Commons Lang提供org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs),将a作为参数,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; } }
Leo

1

String在Java中有很多设施可以从s 获取数字(反之亦然)。您可能要跳过正则表达式部分,以免麻烦。

例如,您可以尝试看看有什么Double.parseDouble(String s)回报。NumberFormatException如果在字符串中找不到合适的值,则应抛出。我建议使用此技术,因为您实际上可以利用String以数字类型表示的值。


5
将异常用作测试您的输入的原因可能不是一个好主意,异常会产生大量开销。
Ofir Luzon 2013年

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()。这会立即告诉您String是仅数字(还是适当数字)。如果需要处理更长的数字字符串,则BigIntegerBigDecimal都接受字符串的构造函数。如果您尝试向其传递非数字(当然是整数或十进制,基于您选择的数字),则上述任何一个都会引发NumberFormatException。或者,根据您的要求,只需迭代String中的字符并检查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();
    }
}

您的代码仍然可以被“ 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();
    }

0

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

因此,parseInt()不太好,但是正则表达式是一种不错的解决方案,但要注意以下几点:
-fractions-
负数
-decimal分隔符在争用中可能有所不同(例如','或'。')-
有时允许使用所谓的千位分隔符,例如空格或逗号,例如12,324,1000.355

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


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

今天必须使用此功能,所以只发布了我的修改内容。包括货币,数千个逗号或句点表示法以及一些验证。不包括其他货币符号(欧元,美分),验证逗号为每三位数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.