繁体   English   中英

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

[英]Java String - See if a string contains only numbers and not letters

我在整个应用程序中加载了一个字符串,它从数字变为字母等。 我有一个简单的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; 
}

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

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)

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

这就是我将如何做到的:

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

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

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

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

JMH测试

测试比较Character.isDigitPattern.matcher().matchesLong.parseLong与检查字符值的性能。

这些方法可以为非 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而不是创建额外的数组,另一种使用字符代码的IntStream
  • 如果为循环测试用例找到非数字,则添加立即中断
  • 对于循环测试用例,为空字符串返回 false

2018 年 2 月 23 日更新

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

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

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

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

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

希望这会对某人有所帮助!

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

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

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

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

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

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

您可以使用 Regex.Match

if(text.matches("\\d*")&& text.length() > 2){
    System.out.println("number");
}

或者你可以使用像Integer.parseInt(String)或更好的Long.parseLong(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
}

在 Java 中有很多工具可以从String获取数字(反之亦然)。 您可能想跳过正则表达式部分,以免自己陷入复杂的境地。

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

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

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

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

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

    return isDigit;
}
StringUtils.isNumeric("1234")

这很好用。

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

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

                }
                else if (Character.isLetter())
                {

                }

工作测试示例

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() 不是很好,但正则表达式是一个优雅的解决方案,但请注意以下事项:
-分数
-负数
-decimal 分隔符可能因contries 不同(例如',' 或'.')
- 有时允许使用所谓的千位分隔符,例如空格或逗号,例如 12,324,1000.355

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

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

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

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

}

这是一个示例。 根据需要仅查找 String 和 Process 格式中的数字。

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

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

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

String data = "12345";
boolean isOnlyNumbers = data.chars().allMatch(Character::isDigit);
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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM