Perl 욕심없는 정규식 일치가 예상보다 뛰어납니다.

Perl 욕심없는 정규식 일치가 예상보다 뛰어납니다.

일부 출력을 제거해야 하는 다음 텍스트가 있습니다 wdiff.

text='Иса Мәсіхтің елшісі Петірден [-(-] осы күнәкар дүниеде [-)-] жат жерлік болып, Понти, Ғалатия, [-Қападоқия, Азия және Бітүния аймақтарында шашыраған [ сенушілерге дұғай сәлем ].-] {+Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]+}'

[- -]탐욕스럽지 않은 Perl 정규식을 사용하여 텍스트 블록을 제거하려고 하는데 \[-.*?-\]이전 블록과도 일치합니다.

$ perl -pe 's|\[-.*?-\] {\+(\S+… https://t.co/.*)\+}|\1|' <<<"$text"
Иса Мәсіхтің елшісі Петірден Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]

예상 출력:

$ perl -pe 's|\[-.*?-\] {\+(\S+… https://t.co/.*)\+}|\1|' <<<"$text"
Иса Мәсіхтің елшісі Петірден [-(-] осы күнәкар дүниеде [-)-] жат жерлік болып, Понти, Ғалатия, Қападоқия… https://t.co/.......... [Петірдің 1 1:1-5]

답변1

입력 문자열을 다음으로 단순화했습니다 qABxBCzABxBCDEFw. 여기서

A represents [
B represents -
C represents ]
D represents {\+
E represents the text between the +s (including the URL)
F represents \+}
Lower case letters represent everything else.

따라서 입력에 대해 실행할 몇 가지 대체 명령은 다음과 같습니다.

                                  Command                          Output
0. Input text:                                                     qABxBCzABxBCDEFw
1. Non-greedy:                   's|AB.*?BCD(E)F|\1|'              qEw
2. Greedy:                       's|AB.*BCD(E)F|\1|'               qEw
3. Restricted Non-greedy:        's|AB[^B]*?BCD(E)F|\1|'           qABxBCzEw
4. Restricted Greedy:            's|AB[^B]*BCD(E)F|\1|'            qABxBCzEw
5. Constrained Non-greedy:       's|(.*)AB.*?BCD(E)F|\1\2|'        qABxBCzEw
6. Constrained Greedy:           's|(.*)AB.*BCD(E)F|\1\2|'         qABxBCzEw

명령 1은 시도한 명령입니다. 명령 2는 동일하지만 욕심이 없는 것은 아닙니다. 아시다시피, 그들은 동일한 결과를 낳습니다.

탐욕스럽지 않은 것은 다음에만 적용되는 것 같습니다.길이님의 텍스트가 유사한 내용과 일치합니다 .*시작점에는 영향을 주지 않습니다.  정규식 일치는 항상 가능한 한 빨리 시작됩니다. 따라서 AB.*?BC(즉, ) 라고 말하면 \[-.*?-\]일치합니다.첫 번째 [-온라인. 그런 다음 임의의 문자로 끝나는 가능한 가장 짧은 문자열과 일치할 것으로 예상합니다 -]. 당신은 이것이 사실일 것으로 예상할 수도 있습니다 [-(-]. 하지만 좀 더 자세히 살펴보세요. 정규 표현식은 AB.*?BCD(E)F모든 문자로 끝나는 가능한 가장 짧은 문자열과 일치해야 합니다 -] {+. 이로 인해 URL까지 거의 모든 것을 소비하게 됩니다.

나는 당신이 원하는 것을 수행하는 것처럼 보이는 네 가지 대체 명령을 작성했습니다. "제한된" 것(3과 4)은 not 을 검색 AB.*BC하지만 AB[^B]*BC문자 그대로 AB... "..."에는 s가 없습니다 BC. B귀하의 경우 이는 ... [-"..." 에 -]s가 없음을 의미합니다. "제한된" 항목(5 및 6)은 -탐욕스러운 플레이어를 앞에 배치하여 AB.*BC게임을 가능한 한 늦게 시작하도록 강제합니다 . 이 분야에서는 당신이 욕심이 많든 없든 .*상관이 없습니다 .AB.*BC

답변2

당신은부정적인 시선:

perl -pe 's|\[-((?!-\]).)*-\] {\+(\S+… https://t.co/.*)\+}|\2|' <<<$text

문제는 첫 번째 [-일치가 발생할 때입니다. 그러면 모델의 욕심 없음은 아무리 욕심 없음에도 불구하고 원하는 효과를 얻지 못합니다. 부정 예측을 사용하면 문자열을 제외한 모든 항목을 일치시킬 수 -]있으며 그런 다음 해당 부분 이전의 항목만 일치합니다 {+...+}.

관련 정보