我目前遇到的问题是Jekyll与Markdown和LaTeX不兼容。所以我有很多关于$\frac{some}{latex}$
或$$\int^e_v {en} more$$
的文章。
如何将$...$
替换为<span>$...$</span>
,将$$...$$
替换为<div>$$..$$</div>
?
使这项任务变得困难的事情是:
...
可能包含换行符。实际上,...
可能包含任何内容,$
$
被<span>$
取代,第二个被$</span>
取代$...$
和$$...$$
可用于同一文档(但始终至少由一个空格分隔)编辑:我刚看到我也需要一些逃脱。所以这项任务还有一个难度:
\$
不应与上述两种情况中的任何一种相匹配。答案 0 :(得分:3)
我知道你要求使用正则表达式,但是对于你提到的手边处理的边缘情况,你会遇到麻烦。 (如果发布了其他正则表达式解决方案,请将此答案与他们的答案进行比较)。有了这个,可以很容易地改变双和单个TeX标记的行为并在TeX代码中处理转义。这是一个非常简单的pyparsing示例,可以满足您的需求:
from pyparsing import *
D1 = QuotedString("$",escChar='\\')
D2 = QuotedString("$$",escChar='\\')
div_action = lambda x: "<div>$%s$</div>"%x[0]
span_action = lambda x: "<span>$$%s$$</span>"%x[0]
D1.setParseAction(span_action)
D2.setParseAction(div_action)
others = Word(printables)
grammar = OneOrMore(D2 | D1 | others).leaveWhitespace()
用例:
S = "$\LaTeX$ is worth $$x=\$3.40$$"
print grammar.transformString(S)
,并提供:
<span>$\LaTeX$</span> is worth <div>$$x=$3.40$$</div>
答案 1 :(得分:2)
import re
str = "$rac{some}{latex}$$$\int^e_v {en} more$$\$rac{some}{latex}$$$\int^e_v {en} more$$\n$rac{some}{latex}$\n$$\int^e_v {en} more$$\n\$rac{some}{latex}$\n$$\int^e_v {en} more$$"
#first step:
str = re.sub(r'(?<![\\])\$\$([^\$]+)\$\$', "<div>$$\g<1>$$</div>", str)
#second step:
str = re.sub(r'(?<![\$\\])\$([^\$]+)(?:(?<!\<div\>)(?<!\\)\$)', "<span>$\g<1>$</span>", str)
print str
我们仅在$$
次出现时执行替换,将其替换为<div>$$\g<1>$$</div>
(\g<1>
将替换为正则表达式中定义的第一个组。)
str = re.sub(r'(?<![\\])\$\$([^\$]+)\$\$', "<div>$$\g<1>$$</div>", str)
意识到我们正在使用正则表达式 (?<![\\])\$\$([^\$]+)\$\$
regex101 example,其工作方式如下:
(?<![\\]) ...
定义我们匹配的内容...
前面没有\
[在正则表达式中:(?<![\\])
] 。首先,我们说在表达式之前我们不想要\
。... \$\$ ...
定义我们必须在字符串的开头出现$$
。... ([^\$]+)
定义在上一步 [在正则表达式$
] 之后我们想要除[^\$]+
之外的所有内容。然后我们将它放入捕获组(...)
,以便在代码中引用它之后。... \$\$
毕竟我们完成了表达,说我们必须在字符串的最后发生$$
次。我们仅在$
次出现时执行替换,将其替换为<span>$\g<1>$</span>
(同样,\g<1>
将替换为正则表达式中定义的第一个组匹配)
str = re.sub(r'(?<![\$\\])\$([^\$]+)(?:(?<!\<div\>)(?<!\\)\$)', "<span>$\g<1>$</span>", str)
还要意识到我们正在使用其他正则表达式 (?<![\$\\])\$([^\$]+)(?:(?<!\<div\>)(?<!\\)\$)
(是的,有点难)regex101 example,它的工作方式如下:
(?<![\$\\]) ...
定义我们匹配的内容...
前面没有\
或 a $
[在...正则表达式:(?<![\\\$])
] 。首先,我们说我们不想在开头使用\
或$
。... \$ ...
定义我们的字符串需要以一个$
... ([^\$]+) ...
定义一个捕获组,其中包含$
以外的所有内容,以备将来回拨。... (?:(?<!\<div\>)(?<!\\)\$)
我们说完我们的字符串以$
结尾,但前面没有div [在正则表达式中:?<!\<div\>)
] 或{{ 1}} [在正则表达式中:\
] 。 (然后我们把它全部放到一个非捕获组中,说所有这些只是一件事(?<!\\)
)注意:也许有更有效的方法来获得此结果。