TeX 파일에는 다음 명령이 있고 \q{aaa}{blablabla}
매개변수를 분리하고 싶습니다 blablabla
. 나는 sed를 사용하여 그것을 알아 냈습니다.
sed 's/\q{([^}\{])}{([^}\{])}/\2/g'
그리고 그것은 훌륭하게 작동합니다.
문제는있을 때중첩됨패턴에 맞춰 교정기 안쪽 교정기를 유지하고 싶어요. 즉, 만약
\q{aaa}{blablabla \label{BBB}}
원하는 출력은
blablabla \label{BBB}
예를 들어, 계속해서 유지하고 싶은 여러 LaTeX 명령을 상상할 수 있습니다.
\q{aaa}{blablabla \label{BBB} blablabla \includegraphics{ccc.eps} blablabla \cite{somebody_year} blablabla
\begin{itemize}
\item AAA
\item BBB
\end{itemize}
blablabla to conclude}
이 극단적인 MWE의 예상 결과는 다음과 같습니다.
blablabla \label{BBB} blablabla \includegraphics{ccc.eps} blablabla \cite{somebody_year} blablabla
\begin{itemize}
\item AAA
\item BBB
\end{itemize}
blablabla to conclude
이러한 예는 매우 (아마도 너무) 복잡한 예입니다. 왜냐하면 내 검색의 최종 목표는 (검토 과정 중) 원고 수정을 최적화하는 것이기 때문입니다.
한 줄로 할 수 있을지는 모르겠지만 sed
...
답변1
일반 정규 표현식은 이를 수행할 수 없습니다. 균형 잡힌 괄호가 필요한 언어는 그렇지 않습니다.정규 언어공식적인 의미에서. 따라서 를 사용하면 이 작업을 올바르게 수행할 수 없습니다 sed
. 다행스럽게도 Perl과 같은 것들은 실제로 정규 언어에 국한되지 않는 정규식을 제공합니다.
예를 들어, 이 역겨운 행동(SO에 대한 답변에서 수정됨)대괄호와 일치하는 정규식) 당신이 원하는 것을하는 것 같습니다 :
perl -0 -lne 'print "$2\n\n" while m/ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/gx '
입력이 \q{aaa}{blablabla \label{BBB}} \foo{bar}{not this} \q{aaa}{bleh}
출력을 준다
blablabla \label{BBB}
bleh
즉, 일치하는 부분 사이에 두 개의 개행 문자가 인쇄됩니다. 위에서 언급했듯이 -0
여러 줄의 레이블에서도 작동해야 합니다. 전체 라벨을 얻기 print $2
위해 변경할 수도 있습니다 .print $&
\q{aaa}{...}
이것이 기본적으로 수행하는 작업은 시작 부분이 \\q\{aaa\}
태그의 상수 부분과 일치하고 내부 부분이 (?: [^}{]+ | (?1))*+
중괄호가 없는 문자열이거나 첫 번째 캡처링 그룹 항목(대괄호 세트)에서 반복적으로 일치할 수 있는 항목과 일치하는 것입니다. 안의 물건과 일치하는 교정기 쌍.
.../ \\q\{aaa\} ( \{ ( (?: [^}{]+ | (?1))*+ ) \} )/ '
^1 ^2 | ^2 ^1
| | |
+---------------------+----------+
recurse to group 1
두 번째 캡처 그룹은 출력의 일부를 캡처하는 데 사용됩니다.