[01-12] 범위가 예상대로 작동하지 않는 이유는 무엇입니까?


91

[01-12]정규식 에서 범위 패턴을 사용하여 두 자리 mm를 일치 시키려고하는데 예상대로 작동하지 않습니다.


8
문자 시퀀스가 아니라 문자와 일치 합니다 . 기본적으로 0, 1 대 1 및 2 (즉, 0, 1 및 2)와 일치합니다. 이것을 고려하십시오 : , 이것은 모든 소문자 및 모든 숫자와 일치하지만 단일 문자로만 일치합니다. [a-z0-9]
Lasse V. Karlsen

FWIW I는 두 입력 (최소 / 최대)에서 최적화 된 정규식을 생성하는 스크립트 생성 도구 github.com/jonschlinkert/to-regex-range
jonschlinkert

0 [1-9] | 1 [0-2]-> 0 | 1 | 2-> [] s in a regex는 문자 클래스를 나타냅니다. 범위가 지정되지 않으면 암시 적으로 또는 모든 문자가 지정됩니다.
Badri Gs

순수 정규식과 일치해야합니까? 그렇지 않은 경우 다음을 수행 할 수 있습니다. 1.) 단순히 \d+패턴을 사용하고 , 2.) 일치하는 문자열을 코드의 숫자로 변환합니다. 3.) 같은 숫자 범위를 확인하십시오 if(num >= 0 && num <= 12){ /*do something*/ }. 훨씬 빠르고 유연합니다.
acegs apr

답변:


192

정규식에서 문자 클래스 정의가 작동하는 방식을 오해 한 것 같습니다.

문자열과 일치하는 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 또는 12,이 작품과 같은 :

0[1-9]|1[0-2]

참고 문헌


설명

문자 클래스는 그 자체로 입력 문자열에서 정확히 하나의 문자를 찾으려고 시도 합니다. [01-12]실제로 정의 [012], 3 개 문자의에 대한 입력에서 하나 개의 문자와 일치하는 문자 클래스 0, 1또는를 2.

-범위 정의에서 진행 11단지 포함하는 1. 한편, 무언가 같이 [1-9]포함 1, 2, 3, 4, 5, 6, 7, 8, 9.

초보자는 종종 [this|that]. 이것은 "작동"하지 않습니다. 이 문자 정의를 정의는 [this|a], 그것이 6 개 임의의 문자에 대한 입력에서 하나 개의 문자와 일치 즉 t, h, i, s, |또는 a. (this|that)의도 된 것 보다 더 많습니다 .

참고 문헌


범위 정의 방법

따라서 다음과 같은 패턴 between [24-48] hours이 "작동"하지 않는 것이 분명 합니다. 이 경우 문자 클래스는 [248].

즉, -문자 클래스 정의에서 패턴의 숫자 범위를 정의하지 않습니다. 정규식 엔진은 유한 반복 구문 (예 : a{3,5}3과 5 사이의 일치)을 제외하고 패턴의 숫자를 실제로 "이해"하지 않습니다 a.

범위 정의는 대신 문자의 ASCII / 유니 코드 인코딩을 사용하여 범위를 정의합니다. 문자 0는 10 진수 48로 ASCII로 인코딩됩니다. 9따라서 문자 정의 [0-9]에는 인코딩에서 값이 10 진수 48에서 57 사이 인 모든 문자가 포함됩니다. 오히려 현명, 디자인이이 문자는 0, 1, ..., 9.

또한보십시오


다른 예 : A에서 Z

또 다른 공통 문자 클래스 정의를 살펴 보겠습니다. [a-zA-Z]

ASCII에서 :

  • A= 65, Z= 90
  • a= 97, z= 122

이는 다음을 의미합니다.

  • [a-zA-Z]그리고 [A-Za-z]동등하다
  • 대부분의 풍미에서 [a-Z]잘못된 문자 범위 일 가능성이 높습니다.
    • a(97)이 Z(90) 보다 "보다 큼" 이기 때문입니다.
  • [A-z] 합법적이지만 다음 6 개의 문자도 포함합니다.
    • [(91), \(92), ](93), ^(94), _(95), `(96)

관련 질문


나를 위해 한 자리이면 0을 접두사로 붙이지 않고 개월을 찾고있었습니다. 그리고 저는 이것을 사용했고 ([1-9] | (1 [0-2])) 작동합니다.
bunjeeb

2
참고 사항 : 이 페이지가 수십에 도달하기 전에 한 자릿수 만있는 숫자 범위에 대한 솔루션을 원하는 경우 0[1-9]|1[0-2]작동하지 않습니다. 논리적 인 다음 단계로 변경하면 [1-9]|1[0-2]이해할 수있는 이유 (그것은 일치를위한 중 하나가 작동하지 않습니다 1에서만 10, 11그리고 12). \b(?:[0-9]|1[0-1])\b그것을 방지하기 위해 사용해야 했습니다. \b's는 정규식이 단어 (또는이 경우 숫자) 경계 ( ^& $did n't) 와 일치하는지 확인합니다 . 대괄호는 또는 ( |)를 다른면으로 간주합니다. 마지막으로 ?:대괄호를 사용하여 부분 일치를 만들지 않는 것입니다.
user66001

@polygenelubricants : "1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )이 JS 정규식이 17 이상인 이유를 말씀해 주시겠습니까?
edam

@edam - polygenelubricants는, 그래서 나는,하지만 그때 우리가 될 것입니다 수 있었다 응답 questi ... 대기 ... 이것은이다 질문 당신이에 요구하는 의견 ? 이 사이트 에는 규칙 이 있습니다.;) 새로운 질문이 있으면 질문하십시오. 댓글은 비판과 해명을 요구하고 이에 대한 답변을위한 것입니다.
robinCTS

1
@edam 아, 알겠습니다. 당신은 않은 시간 후에 질문으로-다시 부탁드립니다. 훌륭합니다! 그러나 여기에서 댓글을 삭제하는 것이 좋습니다.
robinCTS

24

[...]구문으로 표시되는 정규식의 문자 클래스 는 입력 의 단일 문자 와 일치 하는 규칙을 지정합니다 . 따라서 대괄호 사이에 쓰는 모든 내용 은 단일 문자 를 일치 시키는 방법을 지정합니다 .

[01-12]따라서 패턴 은 다음과 같이 분류됩니다.

  • 0-단일 숫자 0과 일치
  • 또는 1-1, 1에서 1까지의 범위에있는 단일 숫자와 일치
  • 또는 2, 단일 숫자 2와 일치

따라서 기본적으로 일치하는 것은 0, 1 또는 2입니다.

원하는 일치를 수행하려면 01-12 범위의 두 자리 숫자를 숫자로 일치 시키려면 텍스트로 표시되는 방식에 대해 생각해야합니다.

당신은 :

  • 01-09 (즉, 첫 번째 숫자는 0, 두 번째 숫자는 1-9)
  • 10-12 (즉, 첫 번째 숫자는 1, 두 번째 숫자는 0-2)

그런 다음 다음과 같은 정규 표현식을 작성해야합니다.

  +-- a 0 followed by 1-9
  |
  |      +-- a 1 followed by 0-2
  |      |
<-+--> <-+-->
0[1-9]|1[0-2]
      ^
      |
      +-- vertical bar, this roughly means "OR" in this context

더 짧은 표현식을 얻기 위해 이들을 결합하려는 시도는 유효하지 않은 입력에 대해 거짓 긍정 일치를 제공하여 실패합니다.

예를 들어, 패턴 [0-1][0-9]은 기본적으로 00-19 숫자와 일치하며 이는 원하는 것보다 약간 더 많습니다.

문자 클래스에 대한 자세한 정보를 얻을 수있는 확실한 소스를 찾으려고했지만 지금은이 Google Query for Regex Character Classes 만 드릴 수 있습니다 . 더 많은 정보를 찾을 수 있기를 바랍니다.


9

이것은 또한 작동합니다 :

^([1-9]|[0-1][0-2])$

[1-9] 1에서 9 사이의 단일 숫자와 일치

[0-1][0-2] 10에서 12 사이의 두 자리 숫자와 일치

여기에 좋은 예가 있습니다.


2
정확하게하려면 [0-1][0-2]도 일치합니다 00. 즉, 링크에 대한 +1 (내 답변에 사용).
polygenelubricants 2010 년

2
[0-1][0-2]이 문자열이 좋아하는 수주의 깊게 해석되어야한다 00, 01그리고 02, 그러나 인정하지 않는 03까지 09, 마침내 인정 10, 1112. 이에 대한 올바른 정규식은 [1-9]|1[0-2], 또는 짝수입니다 0*([1-9]|1[0-2])(마지막으로 선행 0을 허용 함).
Luis Colorado

1

[]정규식 의 s는 문자 클래스를 나타냅니다 . 범위를 지정하지 않으면 암시 적으로 또는 그 안의 모든 문자를 함께 사용합니다. 따라서, [abcde]과 동일 (a|b|c|d|e)는 아무것도 포착하지 않는 것을 제외하고; 이 중 하나와 일치합니다 a, b, c, d, 또는 e. 범위가 나타내는 모든 것은 문자 집합입니다 . [ac-eg]"다음 중 하나와 일치 : a; c과 사이의 모든 문자 e; 또는 g". 따라서, 귀하의 경기 중 하나를 일치 "말한다 0; 모든 문자 사이 11( , 단지 1), 또는 2.

당신의 목표는 숫자 범위를 지정 분명하다 : 임의의 숫자 사이 0112두 자리 숫자로 기록. 이 특정 경우에는 다음과 일치시킬 수 있습니다 0[1-9]|1[0-2]. a 0뒤에 1와 사이의 숫자가 9오거나 a 1뒤에 0와 사이의 숫자 가 나옵니다 2. 일반적으로 비슷한 방식으로 모든 숫자 범위를 유효한 정규식으로 변환 할 수 있습니다. 그러나 정규식보다 더 나은 옵션이나 정규식을 구성 할 수있는 기존 함수 나 모듈이있을 수 있습니다. 언어에 따라 다릅니다.


0

polygenelubricants는 문자 클래스 ([]에있는 것)가 문자열이 아닌 문자와 일치하기 때문에 원하는 것보다 0 | 1-1 | 2를 찾을 것이라고 말합니다.


3
0|1-1|2-이 표기법은 매우 오해의 소지가 있습니다. 같은 0|1|2것이 더 정확할 것입니다.
polygenelubricants 2010 년

0

이것을 사용하십시오 :

0?[1-9]|1[012]
  • 07 : 유효
  • 7 : 유효
  • 0 : 일치하지 않음
  • 00 : 일치하지 않음
  • 13 : 일치하지 않음
  • 21 : 일치하지 않음

2018 년 7 월로 패턴을 테스트하려면 다음을 사용하십시오.

/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/

(날짜 범위 : 01/2000 ~ 12/9999)


나는 이것을하는 방법을 알아 내려고 노력했지만 통과 할 0의 세 번째 조건을 얻었습니다.
mkaatman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.