テキストから特定の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}
ステートメント内のフォームには、1つ以上の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}.
PS。私のテキストファイルに多くの小さな修正を加えます。共同編集者が見ることができるように、これらの編集内容を強調表示したいと思います。しかし、強調表示をすべて削除し、テキストをレビュー担当者に送信したいと思います。
この質問はもともと以下から提起された。AWK/SED は、テキストから特定の Latex コマンドを削除し、その後に閉じる括弧を追加します。。たとえば、とても柔らかいです。
答え1
\edit{...}
以下は、最大レベルのコマンドを使用して単純な場合に機能するコマンドです。
perl -00 -lpe 's,\\edit\{( (?: [^}\\]* | \\[a-z]+\{[^}]*\} )+ )\},$1,xg'
途中で(?: [^}\\]* | \\[a-z]+\{[^}]*\} )+
選択肢があります。[^}\\]*
閉じる中括弧やバックスラッシュ(プレーンテキスト)なしで文字列を一致させ、バックスラッシュ、小文字、および\\[a-z]+\{[^}]*\}
一致する中括弧のペア(たとえば)を含む文字列を\url{whatever...}
一致させます。グループ化は(?:...)+
これらの置換と外部括弧のキャプチャを繰り返すので、一致を内側の部分にのみ置き換えることができます\edit{...}
。
-00
Perl は、一度に 1 つの段落で入力を処理し、段落を空行で区切るように指示します。複数の段落にわたるタグを処理する必要がある場合は、入力-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}.
ただし、2つのレベルのコマンドを含む入力は(予想どおり)失敗します\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{...}
。必要に応じて、すべての行をかなり簡単に追加できます。)