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

时间:2012-05-13 22:05:37

标签: java string if-statement

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

19 个答案:

答案 0 :(得分:306)

如果您要将该号码作为文字进行处理,请更改:

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)

答案 1 :(得分:20)

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

答案 2 :(得分:11)

我就是这样做的:

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

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

答案 3 :(得分:7)

性能方面charAt等等比其他解决方案更糟糕,因为至少需要异常处理。

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

JMH测试

测试比较Pattern.matcher().matchesLong.parseLongparseLong的对比与检查字符值的对比。

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

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

结果

请注意,isDigit在第一次测试加载时比## 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 慢近100倍。

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

测试套件

charAt

于2018年2月23日更新

  • 再添加两个案例 - 一个使用IntStream而不是创建额外数组而另一个使用public class memberFragment extends Fragment { private ListView mylistView; private DatabaseReference mDatabase; ArrayList<String> myArrayList = new ArrayList<>(); FirebaseDatabase myFirebase; public memberFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.fragment_member2, container, false); DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference(); DatabaseReference usersRef = rootRef.child("Accounts").child("Users"); ValueEventListener eventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { for(DataSnapshot ds : dataSnapshot.getChildren()) { String name = ds.child("name").getValue(String.class); String date = ds.child("date").getValue(String.class); myArrayList.add("Member Name: "+name + " / " + "Member Until :"+date); Log.d("TAG", name + " / " + date); } final ArrayAdapter<String> myArrayAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,myArrayList); mylistView = (ListView)view.findViewById(R.id.listView); mylistView.setAdapter(myArrayAdapter); } @Override public void onCancelled(DatabaseError databaseError) {} }; usersRef.addListenerForSingleValueEvent(eventListener); // Inflate the layout for this fragment return view; } 个字符代码
  • 如果发现循环测试用例的非数字,则立即添加中断
  • 为循环测试用例的空字符串返回false

于2018年2月23日更新

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

答案 4 :(得分:2)

boolean isNum = text.chars()。allMatch(c - &gt; c&gt; = 48&amp;&amp; c&lt; = 57)

答案 5 :(得分:2)

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

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

答案 6 :(得分:1)

有很多设施可以从Java String获取数字(反之亦然)。您可能希望跳过正则表达式部分以避免自己的复杂性。

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

答案 7 :(得分:1)

您可以使用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
}

答案 8 :(得分:1)

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

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

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

答案 9 :(得分:1)

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

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

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

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

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

答案 10 :(得分:0)

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

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

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

答案 11 :(得分: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");
    }
}

}

答案 12 :(得分: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;
}
}

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

答案 13 :(得分:0)

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

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

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

    return isDigit;
}

答案 14 :(得分:0)

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

因此parseInt()不太好,但是正则表达式是解决此问题的一种优雅解决方案,但请注意以下事项:
分数
-负数
-小数点分隔符可能会有所不同(例如','或'。')
-有时允许使用所谓的千位分隔符,例如空格或逗号,例如12,324,1000.355

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

答案 15 :(得分: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();
    }

答案 16 :(得分:0)

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

                }
                else if (Character.isLetter())
                {

                }

答案 17 :(得分: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;
    }
}

答案 18 :(得分:0)

此代码已经编写完成。如果你不介意(非常)轻微的性能损失 - 这可能不比正则表达式匹配更糟糕 - 使用Integer.parseInt()Double.parseDouble()。如果字符串只是数字(或者数字,视情况而定),那将立即告诉您。如果您需要处理更长的数字字符串,BigIntegerBigDecimal运动构造函数都接受字符串。如果你尝试传递一个非数字(整数或小数,基于你选择的那个,当然)中的任何一个将抛出NumberFormatException。或者,根据您的要求,只需迭代字符串中的字符,然后选中Character.isDigit()和/或Character.isLetter()