2009-08-05 4 views
1

내가정규 표현식은

내가 시작 및 종료 시간을 추출 할
1-4pm 
1pm-5pm 
noon to 11pm 
noon to midnight 
etc. 

같은 패턴을 혼합 포함되어있을 수 있습니다 데이터를 분석 할 시간 범위를 일치합니다. 정규식을 통해 어떻게 이것을 얻을 수 있습니까? 가능한 모든 입력 형식을 지원할 수는 없지만 최대를 지원하려면 어떻게해야합니까?


이것은 나의 표현 ^(([AZ] +)?) \는 * ([0-9] {1,2} S · [:]? [0-9] {0 , 2} \ s * [.])? \ s * [- | ~ | \ |/| =] \ s ((? [az] +)? (0-9) {1,2} [?] [0-9] {0,2} \ s * [am | pm | am | pm] [.]))? $

거의 모든 조합을 포함합니다. 난 그냥이 정규식에 최적화가 있는지 알고 싶습니다. 여기서 dayPart는 Timespan이 정오, 자정 등으로 시작할 경우 또는 일요일과 같이 무시할 수있는 값이 있으면 처리 할 모든 비 숫자 자 시작 문자를 사용합니다. startTime은 언제든지 모든 형식의 시간 소비를 시도합니다. endPart와 EndTime도 같습니다.

답변

2

먼저 단일 시점과 일치하는 패턴을 정의하십시오. 예를 들면 다음과 같습니다.

(noon|midnight|[0-9]+\s?(am|pm)?) 

다음으로 구분 기호를 정의하십시오. 아마도 :

마지막으로 두 번째와 두 번째 중 하나를 결합하십시오. 언어를 가정 지원 변수, 같은 :

set timePattern {(noon|midnight|[0-9]+\s?(am|pm)?)} 
set separator {(to|\-)} 
set fullPattern "$timePattern(\s*$separator\s*$timePattern)?" 

당신이 엔진을 통해 당신이 일치하는 식의 부분에서 얻을 수 있어야 통과되면

. 일부 그룹을 캡쳐하지 않아야 할 수도 있지만 독자의 연습 문제로 남겨 두겠습니다. 그러면 시간을 파악하기 위해 개별 부분을 구문 분석해야 할 것입니다. 예를 들어 "1pm"을 1로, "pm"을 구문 분석하고이를 기반으로 시간을 계산하십시오.

이렇게 분해하면 구성 요소를 쉽게 이해할 수 있고 표현이 좀 더 이해하기 쉬워집니다. 주석이있는 여러 줄의 식을 지원하는 동일한 언어에서 일부 기능을 수행 할 수도 있습니다.

+0

분리 기호 표현에서 대시를 벗어나지 않아야합니다. 이는 불필요합니다. +1 접근법. – Tomalak

+0

엄밀히 말하면 꼭 필요한 것은 아닙니다. 특별히 범위 내에서 "-"취급해야하므로 습관입니다. 나는 자동적으로 그것을 모든 곳에서 보호하는 경향이있다.

0

많이하지 않고도 "-" 또는 "to"을 기준으로 나눌 수 있습니다.

^(.+) ?(-|to) ?(.+)$ 

이렇게하면 첫 번째 그룹의 시작 시간과 세 번째 그룹의 끝 시간이 캡처됩니다. 보다 구체적인 구문을 원한다면 사용할 정규 표현식을 지정해야합니다.

+0

욕심 많은 "+"는 약간 문제가 있습니다. 첫 번째 paren을'(. +?)'로 변경하는 것이 더 낫다고 생각합니다. 그러나 나는 이것이 당신이 "정규 표현식의 어떤 변종을 지정해야 할 것인가"라는 것을 의미하는 것이라고 읽습니다. ;-) – Tomalak

1

언어에 따라 일치하는 패턴을 '빌드 업'할 수 있습니다. 이 (/ 플렉스 사용하여 파서의 일종을 만들 이유가 확장됩니다으로 훨씬 더 복잡 할 무언가처럼 보이기 때문에,

time_spec = /noon|midnight|\d{1,2}/ 
sep = /-|to/ 
match = /#{time_spec}\s*#{sep}\s*#{time_spec}/ 

그러나 : 루비는, 예를 들어, 당신이 그런 짓을 할 수 있습니다 yacc?) 정규 표현식보다 훨씬 더 잘 유지됩니까? 1 pm/1p/13:00/13 정규식과 같은 입력 범위를 지원하기 시작할 때 더 많은 문제를 만들고 해결책을 제시하십시오.