2017-12-05 12 views
1

저는 초급 python 프로그래머입니다. 정규식을 사용하여 목록에 추가 할 그룹을 만들려고합니다. 내가 뭘 원하는지 여부를 하나의 정규식으로 덮여있을 수 있는지, 아니면 내가 하나 이상의 정규식을 통해 텍스트를 전달해야하는지 잘 모르겠습니다.regex를 사용하여 빈 그룹을 추가하십시오.

테스트 데이터 :

궁시렁 궁시렁 0.003 40 40.00

yadayada 나중에 55

yaaaaaaya 100.0000 4

내 정규식 : 내가 얻을

(\w+ *\w* *\w*) (\d*\.*\d*) *(\d*\.*\d*) *(\d*\.*\d*)\n 

그룹 :

'궁시렁 궁시렁', '0.003', '40', '40.00'

'100.0000', '비어있는 빈

'yaaaaaaya ','나중에 yadayada ''55 ' 4 ', 빈

하지만 내가 원하는 그룹은 다음과 같습니다

'궁시렁 궁시렁 ','0.003가 ','40 ','40.00 '

가'나중에 yadayada ', 빈, 그들을 PTY, '55 '

'yaaaaaaya '빈'100.0000 ','4 '

비어 (\ D *. * \ D *)기를 도입하는 정규식을 변경하는 것이 가능 그 그룹 중 3 개 미만의 라인에? 번호 그룹이 "오른쪽 정렬"되었습니까?

추가하려고 했습니까? 처음 두 (\ d *) 그룹의 끝으로 이동하지만 동일한 빈 그룹을 가져옵니다.

답변

0

대괄호로 설명하는 내용을 일치 항목을 "오른쪽 맞춤"으로 수행하는 가장 간단한 방법은 다음과 같습니다. 이자형. 나중에 선택적인 서브 표현식의 매칭에 우선 순위를 매기는 것은 선택적인 구성 요소의 "욕심"을 뒤집는 것이다. 파이썬 정규식,이 각각의 정량화 된 요소에 ?를 추가하여 수행됩니다 : 당신의 표현은 매우 진보적이며 특정 잘못 형성된 입력의 유효성을 검사하지 않습니다

(\w+ *\w* *\w*) (\d*?\.*?\d*?) *?(\d*?\.*?\d*?) *?(\d*?\.*?\d*?)\n 

참고. 이 방법이 효과적이라면, 예를 들어 (| \d+(?:\.\d+)?)과 같이 공백과 숫자가 느리게 일치하도록 특정 그룹을 고정 그룹으로 지정하는 것이 좋습니다 (예 : (|x)((?:x)??)과 같습니다).

편집 : Tim이 지적했듯이이 정규 표현식의 단점은 단순한 허용 성 이상을 요구하며 입력이 약간 변형 된 경우 치명적인 역 추적을 호출 할 수 있습니다. 이 방법을 고수하려는 경우 좀 더 정확한 것을 권 해드립니다 :

(\w+(?: \w+){0,2}) (|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?) ?(|\d+(?:\.\d+)?)\n 

아직도 잘못된 입력을 일치시킬 수 있지만, 적어도 지금은 조금 더 단단한이다.

+0

공백 그룹 일치를 반환하는 정규식 동작을 변경하지 않으며, 원래의 것과 같이 치명적인 백 트랙킹을하는 경향이 있습니다. –

+0

@TimPietzcker 확실하게, downvoting하기 전에 테스트 해주세요. https://regex101.com/r/dtKcH4/1 정규 표현식이 차선 이하라고 동의합니다. 당신이 그를 위해 다시 쓰고 싶다면, 계속하십시오. – jaytea

+0

물론 테스트를 마쳤습니다. 링크 된 예제를 확인하십시오. 동일한 문제가 있습니다. 이제 빈 그룹은 그룹 4 대신 그룹 2이지만, 여기에도 있습니다. –

0

정규식 엔진이 일치하지 않는 경우에 테스트해야하는 순열 수가 기하 급수적으로 늘어나기 때문에 정규식에 여러 가지 문제가 있습니다. 그 중 하나는 catastrophic backtracking의 높은 위험도입니다. 또 다른 문제는 \w도 숫자와 일치하므로 첫 번째 그룹에 포함하지 않을 숫자가 포함될 수 있습니다.

또한 "동적으로 커지는"정규식의 경우 \G 또는 \K 앵커와 같은 "일치 계속"기능이 필요하지만 Python에서는이를 지원하지 않습니다.

가장 좋은 방법은 (A float로 변환 보내고 try에 의해 예를 들면) 숫자가 포함 된 경우 각 문자열을 확인하고 그에 따라 행동, 문자열로 .split() 문자열하는 것입니다.

추가 보너스 : 매우 복잡한 정규식 대신 읽을 수있는 파이썬 스크립트가 있습니다.