2015-03-15 7 views
1

EDIT: регулярное выражение с тестированием, примеры и решения здесь: https://www.regex101.com/r/rY7uI4/2

Я пытаюсь преобразовать содержание TeX (который мы будет считаться содержащимся в переменной foo), так что разделители $$ будут преобразованы в стандарт TeX \[ и \]. Я играл с regex101, но до сих пор не повезло.

В идеале, ожидаемый результат, который дал этот вход:

text 
$$ math $$ 

$$ 
math 
$$ 

text $$math$$ text 

выход является следующий

text 
\[ math \] 

\[ 
math 
\] 

text \[math\] text 

Возможно регулярное выражение не лучший инструмент, чтобы сделать это, но я не нашел никакого другого инструмент для выполнения задачи. Спасибо за любую помощь!

EDIT: добавить более сложный (и реалистичный) TestCase:

$$\alpha \quad \beta \quad \varepsilon \quad \varphi \quad \mathbb{R} \quad \mathcal{C}([0,1]) \quad \mathfrak{R}([0,2\pi]) \quad \mathscr{C}(\mathbb{R})$$ 
$$\vec{x} \in \mathbb{R}^n, \quad \underline{x}\in \mathbb{R}^m, \quad \mathbf{x}\in \mathbb{R}^m \$$$string 

должно привести к:

\[\alpha \quad \beta \quad \varepsilon \quad \varphi \quad \mathbb{R} \quad \mathcal{C}([0,1]) \quad \mathfrak{R}([0,2\pi]) \quad \mathscr{C}(\mathbb{R})\] 
\[\vec{x} \in \mathbb{R}^n, \quad \underline{x}\in \mathbb{R}^m, \quad \mathbf{x}\in \mathbb{R}^m \$\]string 

Обратите внимание на prescence сбежавшего $ в конце второй строки ,

+0

Вы не можете использовать простую 'str.replace'? – vaultah

+0

Если вы хотите заменить фиксированные строки (не * шаблоны *) другими фиксированными строками, стандартная функция замены строки вопроса - это то, что вы хотите. Не переусердствуйте. – Tomalak

+0

К сожалению, str.replace заменит все вхождения, которые он найдет, в то время как я только хочу, для каждой пары '$$', первая '$$' будет заменена на' \ [', а вторая с' \] ' – Roophie

ответ

1

Используйте неживое регулярное выражение.

print re.sub(r'\$\$(.*?)\$\$',r'\[\1\]',s) 

Если вы не хотите, чтобы рассмотреть сбежавшего символ доллара, то используйте отрицательное для проверки 'назад, является ли последний $$ не предшествует символ обратной косой черты или нет.

print re.sub(r'(?s)(?<!\\)\$\$(.*?)(?<!\\)\$\$',r'\[\1\]',s) 

Добавить DOTALL модификатор (?s) в начале, чтобы сделать точку в своем регулярном выражении, чтобы соответствовать также символы новой строки (разрывы строк).

+0

почти идеально, даже если он не сработает: '$$ test \ $$$ string' – Roophie

+0

, так что вы не хотите рассматривать escape-код $? попробуйте '\ $ \ $ (. *?) (?

+0

да, точно. Это почти все, однако, это ломается, если вход содержит символы новой строки (которые также появляются довольно часто). – Roophie

2

Вы можете использовать re.sub с capturing groups следующим образом:

>>> import re 
>>> s="""text 
... $$ math $$ 
... 
... $$ 
... math 
... $$ 
... 
... text $$math$$ text""" 
>>> print re.sub(r'\$\$\s?(\w+)\s?\$\$',r'\[\1\]',s) 
text 
\[math\] 

\[math\] 

text \[math\] text 

\1 первая группа соответствует в шаблоне регулярного выражения в этом случае (\w+)

Edit: ибо, если вы можете иметь больше текста между $$ как вы добавляете в свое редактирование, вам просто нужно изменить \w, которые соответствуют символам слов с .+, чтобы соответствовать любому персонажу с длиной больше, чем 1.

>>>re.sub(r'\${2,}\s?(.+?)\s?\${2,}',r'[\1]',s) 
+0

привет! спасибо, первая версия действительно правильная (мне нужно '\ [', а не '['), и я подтверждаю, что это работает !!! – Roophie

+2

@Roophie Добро пожаловать! – Kasramvd

+0

Прошу прощения, я говорил слишком рано: строка, такая как '$$ \ alpha \ quad \ beta \ quad \ varepsilon \ quad \ varphi \ quad \ mathbb {R} \ quad \ mathcal {C} ([0,1 ]) \ quad \ mathfrak {R} ([0,2 \ pi]) \ quad \ $ \ mathscr {C} (\ mathbb {R}) $$ '(очень типичный в документе TeX) не признается регулярное выражение. – Roophie