2016-01-08 2 views
0

Я хочу, чтобы заменить \ EQAlign {...} в \ {начать выравнивать *} ... \ endalign *} для текста ниже:Regex необходимость вложенных фигурных скобок - Perl

$$\eqalign{&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\ {\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+\!m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.}$$ 

Perl кодирования

my $CurBrLoopMany = qw/((?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)*})*[^{}]*)*)/; 

$inxmlstr=~s/\\eqalign\{($CurBrLoopMany)\}/\\begin{align*}$1\\end\{align*}/gs; 

Однако я не мог в состоянии заменить вложенный список скобки (квадратные, фигурные, скобки).

Кому понравилось?

+0

В данном случае, вы можете легко сопрягать с начала строки/конца '$$ 'и решение тривиально. В свою очередь, в общем случае вы сталкиваетесь с * нерегулярным языком, который не может быть проанализирован с помощью регулярного выражения. Но регулярное выражение Perl позволяет вам делать такие вещи своими расширениями *. Посмотрите [здесь] (http://stackoverflow.com/a/2595382/1529709) на пример, как вы могли **, но, вероятно, не должны **, сделайте это. – zb226

+1

Вы говорите 'qw //', который является _quoted words_. Вероятно, вы имели в виду 'qr //'. В этом случае он будет работать в любом случае, потому что в списке есть только одно слово, и по этой причине он присваивает этому _word_ '$ CurBrLoopMany', который, в свою очередь, может быть помещен как строка, содержащая неэкранированные метасимволы в' s ///'. Так что ты в порядке. Но все-таки это неправильно. Вы хотите 'qr //'. :) – simbabque

ответ

2


Ваше регулярное выражение для поиска брекеты {} необходимость один уровень глубже.
Не требуется первая глобальная скобка().
Наконец-то, как «simbabque» сказать это в своем комментарии, вы должны использовать код qr// вместо qw// код для определения регулярного выражения или части регулярного выражения.

Таким образом, вы должны изменить переменную так:

my $CurBrLoopMany = qr/(?:[^{}]*(?:{(?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)})*[^{}]*)*})*[^{}]*)*/; 

Я попробовал его с успехом:

> cat test 
#!/usr/bin/perl -w 
use strict; 
my $inxmlstr = '$$\eqalign{&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\ {\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+\!m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.}$$'; 
print "BEFORE:  $inxmlstr\n"; 
my $CurBrLoopMany = qr/(?:[^{}]*(?:{(?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)})*[^{}]*)*})*[^{}]*)*/; 
$inxmlstr =~ s/\\eqalign\{($CurBrLoopMany)\}/\\begin{align*}$1\\end\{align*}/gs; 
print "AFTER : $inxmlstr\n"; 

> ./test 
BEFORE:  $$\eqalign{&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\ {\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+\!m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.}$$ 
AFTER : $$\begin{align*}&\cases{\mathdot{\bf x}=A{\bf x}+Bu\cr y=H{\bf x}}\quad{\rm with}\ {\bf x}=\left(\matrix{x\cr\mathdot{x}\cr\theta\cr\mathdot{\theta}}\right),\cr&A\!=\!\!\left(\matrix{0&1&0&0\cr 0&0&-{m_{a}\over M}g&0\cr 0&0&0&1\cr 0&0&{(M\!+\!m_{a})\over Ml}g&0}\right)\!,\ B\!=\!\left(\matrix{0\cr{a\over M}\cr 0\cr-{a\over Ml}}\right)\!,\ H^{T}\!=\!\left(\matrix{1\cr 0\cr 1\cr 0}\right)\!.\end{align*}$$ 
+0

благодарит свою работу. – ssr1012

Смежные вопросы