Java String-문자열에 문자가 아닌 숫자 만 포함되어 있는지 확인
응용 프로그램 전체에로드 할 문자열이 있으며 숫자에서 문자 등으로 변경됩니다. 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()
다른 것을 사용하십시오 .
부수적으로 일반적으로 부울 값을 true
또는 과 비교하는 것은 나쁜 습관으로 간주됩니다 false
. if (condition)
또는을 사용하십시오 if (!condition)
.
Apache Commons에서 NumberUtil.isCreatable (String str) 을 사용할 수도 있습니다.
이것이 내가하는 방법입니다.
if(text.matches("^[0-9]*$") && text.length() > 2){
//...
}
는 $
부분 일치 예를 방지 할 수 있습니다; 1B
.
parseInt
최소한 예외 처리가 필요하기 때문에 성능 측면 에서는 다른 솔루션보다 훨씬 나쁩니다.
jmh 테스트를 실행했으며 문자열을 사용하여 문자열을 반복하고 charAt
문자를 경계 문자와 비교하는 것이 문자열에 숫자 만 포함되어 있는지 테스트하는 가장 빠른 방법 이라는 것을 알았습니다 .
JMH 테스트
테스트는 char 값 과 vs. char 값의 성능을 Character.isDigit
비교 합니다.Pattern.matcher().matches
Long.parseLong
이러한 방식은 ASCII가 아닌 문자열과 +/- 기호가 포함 된 문자열에 대해 다른 결과를 생성 할 수 있습니다.
테스트 는 5 번의 워밍업 반복과 5 번의 테스트 반복 으로 처리량 모드에서 실행됩니다 ( 더 클수록 좋습니다 ).
결과
주 parseLong
에 비해 거의 100 배 느린 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
테스트 스위트
@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 일에 업데이트 됨
- 스트림을 사용하지 않고 문자 값을 비교하는 테스트 케이스를 하나 더 추가하십시오 (가장 빠름).
부울 isNum = text.chars (). allMatch (c-> c> = 48 && c <= 57)
아파치 코 몬즈 랭 제공 org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs)
인자 A와 걸립니다, String
그것은 (비 라틴 스크립트에서 번호 포함) 순수하게 숫자로 구성 경우 확인합니다. false
공백, 빼기, 더하기 등의 문자와 쉼표 및 점과 같은 소수점 구분 기호 가 있으면 해당 메서드가 반환 됩니다.
해당 클래스의 다른 메소드는 추가 숫자 점검을 허용합니다.
String
Java 에서 s에서 숫자를 얻는 기능은 많으며 그 반대도 마찬가지입니다. 정규 표현식 부분을 건너 뛰어 복잡한 부분을 피할 수도 있습니다.
예를 들어, 어떤 Double.parseDouble(String s)
결과를 얻을 수 있는지 시도해 볼 수 있습니다. NumberFormatException
문자열에서 적절한 값을 찾지 못하면를 던져야 합니다. 이 기술을 제안하는 것은 실제로 String
숫자 유형으로 표시된 값을 사용할 수 있기 때문 입니다.
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
}
아래 정규식을 사용하여 문자열에 숫자 만 있는지 여부를 확인할 수 있습니다.
if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))
true
문자열에 숫자가 아닌 숫자가 포함되어 있으면 위의 두 조건이 모두 반환 됩니다. 에 false
, 문자열은 숫자 만이있다.
ALPHABETS 만 포함 된 문자열을 간단히 확인하려면 다음 코드를 사용하십시오.
if (text.matches("[a-zA-Z]+"){
// your operations
}
NUMBER 만 포함하는 문자열을 간단히 확인하려면 다음 코드를 사용하십시오.
if (text.matches("[0-9]+"){
// your operations
}
Hope this will help to someone!
This code is already written. If you don't mind the (extremely) minor performance hit--which is probably no worse than doing a regex match--use Integer.parseInt() or Double.parseDouble(). That'll tell you right away if a String is only numbers (or is a number, as appropriate). If you need to handle longer strings of numbers, both BigInteger and BigDecimal sport constructors that accept Strings. Any of these will throw a NumberFormatException if you try to pass it a non-number (integral or decimal, based on the one you choose, of course). Alternately, depending on your requirements, just iterate the characters in the String and check Character.isDigit() and/or Character.isLetter().
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;
}
}
Character first_letter_or_number = query.charAt(0);
//------------------------------------------------------------------------------
if (Character.isDigit())
{
}
else if (Character.isLetter())
{
}
Working test example
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();
}
}
Still your code can be break by "1a" etc so you need to check exception
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());
}
}
Method for checking no is string or not
private boolean isStringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
It is a bad practice to involve any exception throwing/handling into such a typical scenario.
Therefore a parseInt() is not nice, but a regex is an elegant solution for this, but take care of the following:
-fractions
-negative numbers
-decimal separator might differ in contries (e.g. ',' or '.')
-sometimes it is allowed to have a so called thousand separator, like a space or a comma e.g. 12,324,1000.355
To handle all the necessary cases in your application you have to be careful, but this regex covers the typical scenarios (positive/negative and fractional, separated by a dot): ^[-+]?\d*.?\d+$
For testing, I recommend regexr.com.
Here is my code, hope this will help you !
public boolean isDigitOnly(String text){
boolean isDigit = false;
if (text.matches("[0-9]+") && text.length() > 2) {
isDigit = true;
}else {
isDigit = false;
}
return isDigit;
}
'IT' 카테고리의 다른 글
리눅스에서 버퍼와 캐시 메모리의 차이점은 무엇입니까? (0) | 2020.05.29 |
---|---|
더 우아한“ps aux | (0) | 2020.05.29 |
문자열의 마지막 문자는 어떻게 얻습니까? (0) | 2020.05.29 |
튜플을 목록으로 변환 (0) | 2020.05.29 |
헤더 X-Powered-By : Express를 제거 할 수 없습니다 : (0) | 2020.05.29 |