목록의 정수가 항상 1 씩 증가하는 쉼표로 구분 된 10 진수 정수 목록을 일치시킬 수 있습니까?정규식을 사용하여 증가하는 정수의 일치 목록
이 일치해야합니다
이0,1,2,3
8,9,10,11
1999,2000,2001
99,100,101
이 일치하지한다 (전체적으로 - 마지막 두 일치하는 서브 시퀀스가) :
42
3,2,1
1,2,4
10,11,13
목록의 정수가 항상 1 씩 증가하는 쉼표로 구분 된 10 진수 정수 목록을 일치시킬 수 있습니까?정규식을 사용하여 증가하는 정수의 일치 목록
이 일치해야합니다
이0,1,2,3
8,9,10,11
1999,2000,2001
99,100,101
이 일치하지한다 (전체적으로 - 마지막 두 일치하는 서브 시퀀스가) :
42
3,2,1
1,2,4
10,11,13
정규식 엔진을 사용하는 경우 예,이 가능하다 역 참조 및 조건을 지원합니다.
(?=(?&cons))\d+
(?:,(?=(?&cons))\d+)*
,\d+
여기
(?=(?&cons))
는 두 값의 연속이다되도록 술어 대한 자리이다
먼저, 연속 번호 목록 번호의 각 쌍에서 연속리스트로 분해 될 수있다. 로 보일 수 있습니다이 술어는 다음과 같습니다
(?<cons>\b(?:
(?<x>\d*)
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?:9(?= 9*,\g{x}\d (?<y>\g{y}?+ 0)))*
,\g{x}
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
(?(y)\g{y})
# handle the 999 => 1000 case separately
| (?:9(?= 9*,1 (?<z>\g{z}?+ 0)))+
,1\g{z}
)\b)
는 간단한 설명은 999,1000
유형 쌍을 처리하는 두 번째 경우는 이해하기 쉽다 - 그것은 this answer concerned with matching a^n b^n에서 작동하는 방법의 아주 자세한 설명이 있습니다. 이 두 경우의 연결은 9^n ,1 0^n
과 일치해야합니다.
첫 번째 경우는 약간 더 복잡합니다. 첫번째 블록 군는 AND 번째로 디지트인지 N을 캡처
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
: 그것의 큰 부분으로 인해 상기 자릿수를 비교적 상세 진수 숫자를 증가시키는 간단한 경우를 처리 그런 다음 조건부를 사용하여 이러한 그룹 중 어떤 것이 사용되었는지 확인합니다. 그룹 aN이 비어 있지 않으면 다음 숫자는 N + 1이어야합니다.
첫 번째 사례의 나머지 부분은 1999,2000
과 같은 사례를 처리합니다. 이것은 패턴 N 9^n, N+1 0^n
에 다시 속하므로 a^n b^n
을 일치시키고 십진수를 증가시키는 방법의 조합입니다. 1,2
의 간단한 경우는 n = 0 인 제한적인 경우로 처리됩니다.
완료 정규식 : 대안 (?&cons)
술어가 약간 더 직접 재귀 서브 패턴 참조가 지원되는 경우 구현 될 수 https://regex101.com/r/zG4zV0/1
이 경우
(?<cons>\b(?:
(?<x>\d*)
(?:(?<a0>0)|(?<a1>1)|(?<a2>2)|(?<a3>3)|(?<a4>4)
|(?<a5>5)|(?<a6>6)|(?<a7>7)|(?<a8>8))
(?<y>
,\g{x}
(?(a0)1)(?(a1)2)(?(a2)3)(?(a3)4)(?(a4)5)
(?(a5)6)(?(a6)7)(?(a7)8)(?(a8)9)
| 9 (?&y) 0
)
# handle the 999 => 1000 case separately
| (?<z> 9,10 | 9(?&z)0)
)\b)
두 문법 9^n ,1 0^n
, N> = 1 및 prefix N 9^n , prefix N+1 0^n
, n> = 0은 꽤 많이 명시 적으로 작성되었습니다.
완벽한 대안 정규식 : https://regex101.com/r/zG4zV0/3
멋진 게시 할 수 있습니다. _nested back reference_에 관한 일반적인 질문이 있습니다. 정규 표현식에서이 표현식은 (? \ g {y}? + 0)'입니다. 대부분 PCRE와 Perl 호환 _Boost regex_ 엔진을 사용합니다. 때로는 특정 상황에 대한 해결 방법을 사용해야합니다. 예를 들어'(? (? & _ y)? + 0) (? (DEFINE) (?<_y> \ g {y}))'undefined backref' 메시지로 가끔 나를 괴롭히는 경우가 있습니다. 함수 호출이 필요없는 더 나은 해결 방법을 안다면 궁금하십니까? (_workaround https://regex101.com/r/zG4zV0/2_). –
sln
@sln 죄송합니다. 부스트 정규식 엔진에 익숙하지 않습니다. 내가 올바르게 이해한다면, 문제는 부스트가 아직 완전히 일치하지 않은 그룹에 대한 하위 참조를 지원하지 않는다는 것입니다. 이 경우 귀하의 해결 방법은 합리적인 것으로 보입니다. 또한 재귀 하위 패턴 참조를 기반으로하는 대체 솔루션을 추가했습니다. 아마도 상자 밖에서 작동합니다. – NikiC
파싱하는 동안 컴파일 시간이 있습니다 :'아직 완전히 (전체적으로) 파싱되지 않은 그룹 '. 따라서 부모 캡쳐 그룹에 대한 참조입니다. 이 문제는 그룹이 열렸을 때 내부 마크가 재귀 구문 분석을 통해 추가되기 전에이 마크에 대한 역주를 허용함으로써 해결되었습니다. 이전에는'''닫는 중 구문이 해석되었을 때만이 백 마크를 허용했습니다. 그것은 단순한 비트 마스크'm_backrefs | = 1 << (markid-1)'입니다. 닫는 괄호가 발견되지 않으면 오류가 생성되고 모든 것이 unwind됩니다. 예상대로 작동합니다. 나는 이것을 다른 mods에 추가한다. – sln