과 일치하는 정규 정수 리터럴

0

질문

내 생각에 대한 구문 분석의 목록을 정수(재산에서 문자열). 그러나,나 가고 싶은 그냥 넘어 긍정적이고 부정적인 진수 값과 분석 이 어떤 문자열을 나타내는 Java 정수 문자(JLS17) 로에서 찾을 수 있습니다. 마찬가지로,를 관대하는 관련하여 모든 접두어,분리 및 부록은 주위에 정수이다. 다시 말해서,나는 그들을 찾기 위해 사용하여 반복되는 통화 Matcher.find().

가 일치하는 정규 표현식을 모든 가능한 Java 정수 리터럴? 그것은 필요가 없는지 확인러.


가 명시적으로 링크 JLS,나는 몇 가지 유효하고 잘못된 숫자:

  • -1다: 1 가 일치하지 마이너스는 단항 연산자(나는 필요한 경우 조정)
  • 0x00_00_00_0F:값이 다섯과 일치로 진수 숫자,밑줄로 별도의 두 nibbles
  • 0b0000_1111:값이 다섯에서 이진치
  • 017:진수 값의 십치
integer java literals regex
2021-11-23 21:48:28
3

최고의 응답

4

무언가가 다음과 같다:

decimal:
(?:0|[1-9](?:_*[0-9])*)[lL]?

수:
0x[a-fA-F0-9](?:_*[a-fA-F0-9])*[lL]?

octal:
0[0-7](?:_*[0-7])*[lL]?

바이너리:
0[bB][01](?:_*[01])*[lL]?

모두 함께:(에 freespacing 모드)

(?:
    0
    (?:
        x [a-fA-F0-9] (?: _* [a-fA-F0-9] )*
      |
        [0-7] (?: _* [0-7] )*
      |
        [bB] [01] (?: _* [01] )*
    )?
  |
    [1-9] (?: _* [0-9] )*
)
[lL]?

테스트

2021-11-23 22:47:19

아,그는 나를 얻습니다. 그것은 여러 밑줄을까요? 어쩌면 그 ?*?
Maarten Bodewes

@MaartenBodewes:내가 이해하는 문서,밑줄을 가정하지 않는 contigous 지만,아마도 내가 부 잘못입니까? (에 다른 단어입니다 1____1 도 가능한가요?). 참고하는 그룹 내에 있는 선택적인 밑줄은,결국 반복됩니다.
Casimir et Hippolyte

허,할 수 있는 사람을 다시 쓰는 regex? 나는 듯 업데이트할 수 있도록 그것은(시험 버전은 여전히 있었다? 대신*)....
Maarten Bodewes

덕분에 다시,게재했 는 대답이 구문 분석하는 정수를 사용하여뿐만 아니라 일반현 구문을 기반으로 심령에 정규식으로 이루어져 있습니다.
Maarten Bodewes
0

후에서 답 Casimir 하기로 결정했다 조금 더 나아가 구현되는 코드를 실제로 구문 분석의 정수,뿐만 아니라 아래에 포함되어 있습니다. 그것이 포함되어 마이너스 플러스 상징하더라도 사람들은 공식적으로 일부의 정수 리터럴에서 설명한 대로 JLS;그들은 단항 연산자입니다.

package nl.owlstead.ifprops;

import java.math.BigInteger;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class JavaIntegerParser {
    private static final Pattern BINARY = Pattern.compile("(0b)([01](?:_*[01])*)(L?)", Pattern.CASE_INSENSITIVE);
    private static final Pattern OCTAL = Pattern.compile("(0)([0-7](?:_*[0-7])*)(L?)", Pattern.CASE_INSENSITIVE);
    private static final Pattern DECIMAL = Pattern.compile("()(0|(?:[1-9](?:_*[0-9])*))(L?)", Pattern.CASE_INSENSITIVE);
    private static final Pattern HEXADECIMAL = Pattern.compile("(0x)([0-9a-f](?:_*[0-9a-f])*)(L?)", Pattern.CASE_INSENSITIVE);
   
    // NOTE: OCTAL should be before DECIMAL if this is used to find the pattern
    private static final Pattern SIGNED_INTEGER_LITERAL = Pattern.compile(
            "(?:([+-])\\s*)?(" + 
            BINARY + "|" + OCTAL + "|" + DECIMAL + "|" + HEXADECIMAL + 
            ")", Pattern.CASE_INSENSITIVE);
        
    public static int parseJavaInteger(String javaInteger) throws NumberFormatException {
        BigInteger value = parseIntegerAsBigInt(javaInteger);
        try {
            return value.intValueExact();
        } catch (@SuppressWarnings("unused") ArithmeticException e) {
            throw new NumberFormatException("Number is not between Integer.MIN_VALUE and Integer.MAX_VALUE");
        }
    }
    
    public static long parseJavaLong(String javaLong) throws NumberFormatException {
        BigInteger value = parseIntegerAsBigInt(javaLong);
        try {
            return value.longValueExact();
        } catch (@SuppressWarnings("unused") ArithmeticException e) {
            throw new NumberFormatException("Number is not between Integer.MIN_VALUE and Integer.MAX_VALUE");
        }
    }

    private static BigInteger parseIntegerAsBigInt(String javaLiteral) {
        Matcher intMatcher = SIGNED_INTEGER_LITERAL.matcher(javaLiteral);
        if (!intMatcher.matches()) {
            throw new NumberFormatException(javaLiteral + " is not recognized as a Java integer literal");
        }
        
        String signGroup = intMatcher.group(1);
        String prefixAndValueGroup = intMatcher.group(2);
        String radixGroup = "";
        String valueGroup = "";
        // String longGroup = "";
        List<Pattern> patterns = List.of(BINARY, OCTAL, DECIMAL, HEXADECIMAL);
        for (Pattern pattern : patterns) {
            Matcher specificMatcher = pattern.matcher(prefixAndValueGroup);
            if (specificMatcher.matches()) {
                radixGroup = specificMatcher.group(1);
                valueGroup = specificMatcher.group(2);
                // longGroup = specificMatcher.group(3);
                break;
            }
        }
        
        if (valueGroup == null) {
            throw new RuntimeException("Number both matches but doesn't contain a value (parser error)");
        }

        BigInteger sign = signGroup != null && signGroup.matches("-") ? BigInteger.ONE.negate() : BigInteger.ONE; 
        
        int radix;
        switch (radixGroup.toLowerCase()) {
        case "0b":
            radix = 2;
            break;
        case "0":
            radix = 8;
            break;
        case "":
            radix = 10;
            break;
        case "0x":
            radix = 16;
            break;
        default:
            throw new RuntimeException();
        }
 
        BigInteger value = new BigInteger(valueGroup.replaceAll("_", ""), radix).multiply(sign);
        return value;
    }
}

도를 사용하여 코드를 찾아 여러 정수 문자열에서,하지만 잘되지 않았다. 문제는 그 어떤 잘못된 리터럴 등 0__0 었으로 받아들여 두 리터럴 가치로 정확하게 당신이 원하는 무슨이 아닙. 그래서를 이용하시기 바랍 regex 만을 감지하는 경우 문자열은 실제로 정수 및 별도의 정수를 사용하여 예를 들어 String.split(SEPARATOR_REGEX).

충분히 재미 내 Eclipse IDE 받았다 0__0 리터럴 경우에도 그것은 공식적으로 준수하지 않을 JLS. 지는 빅지만,이상한 그럼에도 불구하고.

2021-11-23 22:27:00

신속 응답,미안해 너무 피곤해서 가상의 깊이만:알아서 하지 너무 많이 사용하 캡쳐 특히지 않는 경우에는 그들이 필요합니다. 비 캡처 그룹 (?:....) (캡처 비용).
Casimir et Hippolyte

내가 사용하는 비 캡처하는 그룹이 가능합니다. 어쩌면을 검증하는 전체 정수가를 제거할 수 있습니 나는 그들이 필요하지 않 초기 일치합니다. 또 어쩌면 내가 제거할 수 있는 전 초기치 및 그냥 떠나 루프 유효성을 검사하는 가능한 모든 포맷입니다. 하지만,결국 우리가 일치하는 정수,하지 않는 페이지와 페이지의 텍스트를...
Maarten Bodewes
-1

니다. 에서 간단한 측면,기초 2,8,10 번호를 용하는 동일한 패턴이 이들 값은 모든 숫자로 되어 있습니다. 하지만,당신은 아마 당신이 원하는 각 유형입니다. 문제는 당신이하지 않았을 명확하게 당신의 의도입니다. 나는 가정을 원하는 표현을 검증하이 무엇 기본 특정 값입니다.

String base10Regex = "[0-9]+";
String base2Regex = "[0-1]+";
String base8Regex = "[0-7]+";
String base16Regex = "^[0-9A-F]+$";

에 대한 진수 값을해야 합니다 추가 식을 확인하는 선택적인 캐릭터 "^[\\+|-]?". 에 대한 hex 값을 것으로 예상된다면,값을 시작으로"0x",이 앞에 추가하는 표현으로 그 리터럴 값입니다.

2021-12-09 23:34:58

밑줄을 사용하지 않고 그에 일치하지 않는 실제 정수입니다. 그리고 물론 경계(^$도)와 함께 작동하지 않을 찾지만,그 시작이...
Maarten Bodewes

@MaartenBodewes 감사합니다. 내가 당신 부 밑줄지만,당신이 무엇을 의미하지 않는 실제와 일치 정수가? 도 몰랐고 경계 작동하지 않으로 find. 그래서,당신을 감사하는 것 뿐만 아니라.
hfontanez

Sorry,내 나쁜에,나는 그와 맞지 않을 리터럴에 표시된 대로 JLS,를 필요로 하는 곳에 0x0X 에 대한 hexadecimals etc.
Maarten Bodewes

@MaartenBodewes 를 제외하고 내가 쓴"당신이 기대 값을 시작으로"0x",이 앞에 추가하는 식으로 이러한 문자 값"
hfontanez

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................