在查找和替换期间隐藏文本位的强大方法?
Posted
技术标签:
【中文标题】在查找和替换期间隐藏文本位的强大方法?【英文标题】:Robust way to hide bits of text during a find-and-replace? 【发布时间】:2011-11-11 17:32:05 【问题描述】:假设我有一些文字:
<hello> <world> <:how> are <you>
现在我想对它进行 html 编码,这样<>
s 就不会搞砸了。但是<:how>
很特别,因为它里面有一个:
,所以我不想碰它。
我可以使用正则表达式将其替换为how
,然后进行 HTML 编码,然后将其替换回来。
但是如果something
已经出现在代码中的某处怎么办?然后 something
将被转换为 <:something>
,而它应该保持原样。
过去我遇到过几次这个问题,但仍然没有找到解决它的好方法。人们是否只是选择了一些真正晦涩的东西来替换并希望它在其他地方不存在,还是有合适的方法来做到这一点?
【问题讨论】:
【参考方案1】:使用正则表达式进行 HTML 解析 is bad。但是让我们考虑一下您只是修复了一小段自己的代码。
考虑这个正则表达式:<(?!:)
:它匹配任何&lt;
,它后面没有:
,但是冒号不包括在匹配中,所以你可以使用&lt;
的替换字符串。
找出您最喜欢的文本编辑器中“使用正则表达式”复选框的位置。 (在 vi 中,它隐含地存在,检查。)上面的表达式只有在你的编辑器支持正则表达式语法时才有效;大多数人现在都这样做了。
但你原来的方法也是可行的。如果在一个正则表达式中枚举几个复杂的排除模式是不切实际的,您可以暂时用一些字符串替换这些模式。只需让这些琴弦神仙独一无二。我敢打赌,如果您将 <:
替换为 LESS=THAN=AND=COLON
,那么您与某些东西发生冲突或忘记该字符串代表什么的可能性几乎为零。是的,这些临时字符串是令人眼花缭乱:这让您忘记将它们替换回来的机会非常渺茫。
【讨论】:
好吧,我在 Python 中执行此操作,并且只是使用标准cgi.escape
进行 HTML 转义,但我想我可以编写自己的转义函数来跳过 <:blah>
s .但这没有抓住重点。格式可能完全不同,可能根本不涉及 HTML。问题是如何安全地从查找和替换中隐藏大块文本(一般意义上)?另外,仅供参考,我不是用正则表达式解析 HTML。
我明白了。但是,一旦它模糊相关,我就没有提到这么棒的帖子 :) 如果您不是在文本编辑器中执行此操作,那么它越简单。使用正则表达式查找您可能需要替换的(简单)模式,检查它是否正常(通过任何方式)并在您喜欢时替换它。请参阅re
的 API。不过,仅使用 str.replace()
就没有简单的方法可以做到这一点。
所以简而言之,有条件地只替换我想要的元素,而不是全部替换。我可以更轻松地使用正则表达式回调来做到这一点。很公平。但是,如果我想对文本进行 3rd 方转换,仍然无法工作。【参考方案2】:
您可以基于某些无法在编码过程中幸存的字符实现转义机制。例如,如果您对您的输入进行 html 编码,您知道之后您将不会有任何 <
或 >
字符,因为它们被 html 实体替换。
因此,您可以使用由<
或>
组成的字符串作为转义码。如果您要在浏览器中显示最终代码,您可以使用 <!-- TOKEN -->
之类的代码作为转义码,因为它不会影响可视化。
您的编码过程可能如下所示:
输入字符串:<hello> world <:how> are <you>
将&lt;xxx&gt;
替换为&lt;xxx&gt;
,其中xxx 不以:
开头
&lt;hello&gt; world <:how> are &lt;you&gt;
将<:xxx>
替换为<!-- TOKEN -->xxx
&lt;hello&gt; world <!-- TOKEN -->how are &lt;you&gt;
在浏览器中显示,world
和how
会看起来相同,但它们会保留解码信息。实际上,相应的解码过程是:
&lt;hello&gt; world <!-- TOKEN -->how are &lt;you&gt;
将<!-- TOKEN -->xxx
替换为<:xxx>
&lt;hello&gt; world <:how> are &lt;you&gt;
将&lt;xxx&gt;
替换为&lt;xxx&gt;
<hello> world <:how> are <you>
就像我说的那样,由于您的转义码所基于的字符不能自行出现在编码文本中,因此输入 &lt;!-- TOKEN --&gt;how
不会破坏编码/解码过程,因为它会被编码为&lt;!-- TOKEN --&gt;how
并且因此正确反转。
【讨论】:
以上是关于在查找和替换期间隐藏文本位的强大方法?的主要内容,如果未能解决你的问题,请参考以下文章