욕심이없는 부정적인 일치를하려고하는데, 그것을 캡처해야합니다. 파이썬에서 이러한 플래그를 사용하고 있습니다. re.LOCALE | re.MULTILINE, 각 필드가 백 슬래시로 새 행에서 시작하는 일부 텍스트 파일 '데이터베이스'의 다중 행 정리를 수행합니다. 각 레코드는 \ lx 필드로 시작합니다.파이썬 정규 표현식에서 부정적 일치 캡처하기
\lx foo
\ps n
\nt note 1
\ps v
\nt note
\ge happy
\nt note 2
\ge lonely
\nt note 3
\ge lonely
\dt 19/Dec/2011
\lx bar
...
각 \ ge 필드의 레코드 안의 어딘가에 \ ps 필드가 하나씩 있는지 확인하려고합니다. 현재 하나의 \ ps 뒤에 여러 개의 \ ge이 붙어 있기 때문에 위의 두 외로운 \ ge와 같이 복사해야합니다.
여기에 필요한 로직의 대부분은 \ ps 필드 이후이지만 다른 \ ps 또는 \ lx와 충돌하기 전에 \ ge을 찾은 다음 다른 \ ge을 찾으십시오. \ ps 필드가 두 번째 \ ge 바로 전에 복사 될 수 있도록 모든 것을 캡처하십시오.
내 비 기능적인 시도는 다음과 같습니다. 이 교체 :이와
^(\\ps\b.*?\n)((?!^\\(ps|lx)*?)^(\\ge.*?\n)((?!^\\ps)*?)^(\\ge.*?\n)
을 : 나는 심지어 작은 파일 (34 개 라인 긴)에 메모리 오류를 받고 있어요
\1\2\3\4\1\5
. 물론, 이것이 효과가 있었다고해도, 여러 번 실행해야 할 것입니다. 단지 두 번째 \ ge을 다루는 것이고 세 번째 또는 네 번째 것은 처리하지 않기 때문입니다. 그 점에서 어떤 아이디어라도 나에게 흥미가있을 것입니다.
업데이트 : 약간의 조정이 필요한 경우도 있지만, Alan Moore의 솔루션은 훌륭했습니다. 슬프게도, DOTALL을 꺼야했다. 그렇지 않다면, 첫 번째. * 추후 \ ps 필드를 포함하여 - 욕심이 아닌. *을 포함하여 -을 막을 수 없기 때문이다. 형태. 하지만 (? s) 수식어에 관해서는 이제 정규식 점 정보에서 배울 수있어서 기뻤습니다. 이것은 내가 일반적으로 DOTALL을 끄지 만 여전히 다른 정규 표현식에서 사용하는 것을 허용했다 은이 필수적이다. 일,하지만 위의 예를 수정할 때, 그것은 "주 2"위의 \ 추신을 삽입
^(?P<PS_BLOCK>(?P<PS_LINE>\\ps.*\n)(?:(?!\\(?:ps|lx|ge)).*\n)*\\ge.*\n)(?P<GE_BLOCK>(?:(?!\\(?:ps|lx|ge)).*\n)*\\ge.*\n)
: 여기
내가 필요로하는 한 줄 형식으로 아래로 응축 제안 된 정규식입니다. 또한 \ lxs와 \ ge2를 \ lx와 \ ge (몇 개가 필요 \ b)로 취급하고 있습니다.^(?P<PS_BLOCK>(?P<PS_LINE>\\ps\b.*\n)(?:(?!\\(?:ps|lx|ge)\b).*\n)*\\ge\b.*\n)(?P<AFTER_GE1>(?:(?!\\(?:ps|lx|ge)\b).*\n)*)(?P<GE2_LINE>\\ge\b.*\n)
를이 대체 문자열 : 그래서, 약간 불통 버전으로 갔다 다시
\g<PS_BLOCK>\g<AFTER_GE1>\g<PS_LINE>\g<GE2_LINE>
감사합니다!
당신이하려는 것은 정규 언어 (* "어딘가에 위의 *"와 같은)에서는 불가능합니다. 단순히 파서 또는 뭔가를 작성하고 올바른 출력을 즉시 작성해야합니다. – poke
정규식은 잘못된 도구라고 생각합니다. – MRAB
나는 그것이 한계를 밀고있다는데 동의하지만 내 이유에 대해 thebjorn의 대답에 대한 나의 대답을 보아라. –