텍스트에서 특정 latex 명령을 제거하고 그 뒤에 닫는 대괄호를 추가하되 대괄호 안에 텍스트를 유지하려면 어떻게 해야 합니까? 다음 예에서 제거할 명령은 입니다 \edit{<some staff>}
. 제거해야 하며 \edit{
변경 되지 않은 상태로 유지되어야 합니다.}
<some staff>
SED, AWK, Perl 또는 해당 작업을 수행할 수 있는 모든 것을 자유롭게 제안하십시오.
무의미한 예:
We \edit{Introduce a} model for analyzing \emph{data} from various
experimental designs, \edit{such as paired or \url{http://www/}
longitudinal; as was done 1984 by NN \cite{mycitation} and by NNN
\cite{mycitation2}}.
\command{smth}
명령문 내의 양식에는 하나 이상의 Latex 명령이 있을 수 있습니다 \edit{}
. \command{smth}
그대로 남아야 한다
산출:
We Introduce a model for analyzing \emph{data} from various
experimental designs, such as paired or \url{http://www/}
longitudinal; as was done 1984 by NN \cite{mycitation} and by NNN
\cite{mycitation2}.
추신. 내 텍스트 파일에 많은 작은 수정을 가할 것입니다. 공동작업자가 볼 수 있도록 이러한 편집 내용을 강조표시하고 싶습니다. 하지만 강조 표시를 모두 제거하고 텍스트를 리뷰어에게 보내고 싶습니다.
이 질문은 원래 다음에서 제기되었습니다.AWK/SED는 텍스트에서 특정 Latex 명령을 제거하고 그 뒤에 닫는 대괄호를 추가합니다.. 예를 들어 너무 부드럽습니다.
답변1
\edit{...}
다음은 최대 한 수준의 명령을 사용하여 간단한 경우에 작동하는 명령입니다.
perl -00 -lpe 's,\\edit\{( (?: [^}\\]* | \\[a-z]+\{[^}]*\} )+ )\},$1,xg'
중간에 (?: [^}\\]* | \\[a-z]+\{[^}]*\} )+
대안이 있습니다 . [^}\\]*
닫는 중괄호나 백슬래시(일반 텍스트) 없이 문자열을 일치시키고 \\[a-z]+\{[^}]*\}
백슬래시, 소문자 및 일치하는 중괄호 쌍(예: )이 있는 문자열 \url{whatever...}
을 일치시킵니다. 그룹화는 (?:...)+
이러한 대체와 외부 대괄호 캡처를 반복하므로 일치 항목을 내부 부분으로만 대체할 수 있습니다 \edit{...}
.
-00
Perl은 한 번에 한 문단씩 입력을 처리하고 문단을 빈 줄로 구분하도록 지시합니다. 여러 단락에 걸쳐 있는 태그를 처리해야 하는 경우 -0777
전체 입력을 한 번에 처리하도록 이를 변경합니다( -0
텍스트 파일에 대한 입력이 없기 때문에 NUL로 구분된 입력에도 작동함).
귀하의 예에서는 다음과 같이 작동하는 것 같습니다.
We Introduce a model for analyzing \emph{data} from various
experimental designs, such as paired or \url{http://www/}
longitudinal; as was done 1984 by NN \cite{mycitation} and by NNN
\cite{mycitation2}.
그러나 두 가지 수준의 명령이 포함된 입력의 경우 (예상대로) 실패합니다 \edit{...}
.
Some \edit{\somecmd{\emph{nested} commands} here}.
이동 :
Some \somecmd{\emph{nested} commands here}.
(잘못된 닫는 중괄호가 제거됨)
균형 괄호를 다루는 것은 실제로 약간 까다롭습니다. 예를 들어 다음 질문에서 논의됩니다. Perl 정규식: 중첩된 대괄호 일치.
답변2
간결하지는 않지만 중첩된 명령을 사용하면 잘 수행되는 Python 기반 솔루션이 있습니다.
def command_remove(tex_in, keywords):
# Romove command with curly bracket
# keywords: "hl textbf" mean removing \hl{} and \textbf{}
pattern = '\\\\(' + keywords.replace(' ', '|') + '){'
commands = re.finditer(pattern, tex_in)
idxs_to_del = [] # The index of }
for command in commands:
stack = 0
current_loc = command.span()[1]
while not (tex_in[current_loc] == '}' and stack == 0):
if tex_in[current_loc] == '}':
stack = stack - 1
if tex_in[current_loc] == '{':
stack = stack + 1
current_loc = current_loc + 1
idxs_to_del.append(current_loc)
idxs_to_del = sorted(idxs_to_del, reverse=True) # sort
tex_list = list(tex_in)
for idx in idxs_to_del:
tex_list.pop(idx) # remove }
tex_out = ''.join(tex_list)
tex_out = re.sub(pattern, '', tex_out) # remove \xxx{
return tex_out
정규식을 통해 대상 명령을 찾은 다음 스택을 통해 닫는 괄호의 위치를 찾습니다. 을 위한 tex_out = command_remove(tex_in, "revise textbf")
:tex_in
\hl{Can you} \revise{can a \textbf{can} as a \emph{canner} can} can a can?
우리는 얻을 것이다 tex_out
:
\hl{Can you} can a can as a \emph{canner} can can a can?
자세한 내용(예: 명령줄 실행)은 다음을 참조하세요.latex_command_delete.
답변3
\edit{...}
LaTeX 명령(다른 쌍을 의미)을 사용하여 s를 처리 하려면 정규식에서 재귀를 처리하는 기능을 {...}
사용할 수 있습니다 .perl
perl -pe 's{\\edit(\{((?:[^{}]++|(?1))*)\})}{$2}g' file
(?1)
첫 번째 쌍의 정규 표현식이 호출되고 여기 (...)
에 해당 쌍과 일치하는 정규 표현식이 있습니다 {...}
.
(이스케이프된 중괄호나 \verb
주석은 여기서 처리되지 않으며 s가 여러 줄에 걸쳐 있지 않다고 가정합니다 \edit{...}
. 필요한 경우 모든 줄을 상당히 쉽게 추가할 수 있습니다.)