将“直引号”转换为“弯引号”
Posted
技术标签:
【中文标题】将“直引号”转换为“弯引号”【英文标题】:Converting ″Straight Quotes″ to “Curly Quotes” 【发布时间】:2011-01-13 06:05:44 【问题描述】:我有一个使用基于 javascript 的规则引擎的应用程序。我需要一种将常规直引号转换为弯(或智能)引号的方法。为["]
做一个string.replace
很容易,只是这只会插入一个大写的花括号。
我能想到的最好的方法是用左花引号替换第一次出现的引号,然后用左引号替换所有其他引号,其余的右花引号。
有没有办法使用 Javascript 来实现这一点?
【问题讨论】:
您可能想稍微使用一下文字处理器,看看它使用什么规则来确定要使用哪些引号。据我所知,它们是基于引用的上下文,而不是配对。 【参考方案1】:您可以用左引号替换单词字符前面的所有字符,用右引号替换单词字符后面的所有字符。
str = str.replace(/"(?=\w|$)/g, "“");
str = str.replace(/(?<=\w|^)"/g, "”"); // IF the language supports look-
// behind. Otherwise, see below.
正如下面的 cmets 所指出的,这没有考虑标点符号,但很容易:
/(?<=[\w,.?!\)]|^)"/g
[编辑:]对于不支持后视的语言,比如Javascript,只要你先替换所有的前置,你有两种选择:
str = str.replace(/"/g, "”"); // Replace the rest with right curly quotes
// or...
str = str.replace(/\b"/g, "”"); // Replace any quotes after a word
// boundary with right curly quotes
(我保留了上面的原始解决方案,以防这对使用支持后视的语言的人有所帮助)
【讨论】:
+1 用于实际回答问题。虽然用户应该考虑到它并非在所有情况下都是完美的 - 例如,表示英尺和英寸的破折号。 ...或引用结束的标点符号。 谢谢!这就是我一直在寻找的。一个注释,准确地复制代码给了我一个错误。 '? @BlueVoid - 您对错误的看法是正确的,我发现了这一点,并在您评论时更新了我的答案 :) 小心您的代码 -?=
是一个前瞻,因为它匹配向前看并看到引号,它在您的角色类中。我会在我编辑的答案中使用第一个“替代”解决方案——只需将它们全部替换为 right 大引号 after 替换 left大引号。
@Reesis 好点。无论如何,这简化了事情。效果很好。【参考方案2】:
您可能想看看Pandoc 做了什么——显然使用--smart
选项,它在所有情况下都能正确处理引号(包括例如'tis 和'twere)。
我最近编写了一个 Javascript 排版美化引擎,其中包括引用替换;我基本上使用了Renesis 建议的算法,但目前有一个失败的测试正在等待更智能的解决方案。
如果您有兴趣抄袭我的代码(和/或根据您所做的工作提交补丁),请查看:jsPrettify。 jsprettify.prettifyStr
可以满足您的需求。如果你不想处理 Closure 依赖,有一个 older version 可以独立运行——它甚至可以在 Rhino 中运行。
【讨论】:
Pandoc 加 1。与烘焙自己的正则表达式相比,我尽可能尝试使用成熟且经过测试的工具。手工构建的正则表达式不会过于贪婪,或者不够贪婪,并且它们可能对单词边界和逗号等不敏感。Pandoc 占了大部分以及更多。【参考方案3】:'foo "foo bar" "bar"'.replace(/"([-a-zA-Z0-9 ]+)"/g, function(wholeMatch, m1)
return "“" + m1 + "”";
);
【讨论】:
这不能回答问题。 它将如何处理"John was 6' 4""
?
@Anon,如果没有足够聪明的程序知道什么是英寸和英尺,怎么会处理这个问题?
我见过的东西通常会以正确的方向卷曲引号,但也会以相同的方式卷曲英寸标记。它不做的是卷曲英寸标记,然后以与它应该做的相反的方式卷曲所有其他引号。
@Anon:那么也许你应该发布一个解决方案。【参考方案4】:
以下只是通过交替更改每个引号(但是这个特定示例将省略孤立的引号)。
str.replace(/\"([^\"]*)\"/gi,"“$1”");
只要您正在纹理化的文本没有因不正确使用双引号而搞砸,就可以完美运行。在英语中,引号从不嵌套。
【讨论】:
在英语中有一个合法的情况,这条规则被打破了。当您有连续的段落代表同一演讲者引用的演讲时,必须以适当的引号(单、双、单+双、双+单等)开始每个段落,但是一个省略结束引号,但同一发言人的最后一段除外。【参考方案5】:我认为一般这样的事情一点也不容易,因为您必须准确解释内容中每个双引号字符的含义。也就是说,我要做的是收集我感兴趣的所有文本节点,然后通过并跟踪每个双引号实例的“开/关”(或“奇/偶”;无论如何)性质。然后你就可以知道要使用哪个替换实体了。
【讨论】:
【参考方案6】:我在这里没有找到我想要的逻辑,所以这就是我最终的结果。
value = value.replace(/(^|\s)(")/g, "$1“"); // replace quotes that start a line or follow spaces
value = value.replace(/"/g, "”"); // replace rest of quotes with the back smart quote
我有一个小的文本区域,我需要用弯引号(智能)替换直引号。我只是在 keyup 上执行这个逻辑。我试图让它表现得像 Microsoft Word。
【讨论】:
【参考方案7】:为后代张贴。
按照@Steven Dee 的建议,我去了Pandoc。
我尽量使用成熟且经过测试的工具,而不是烘焙自己的正则表达式。手工构建的正则表达式可能过于贪婪,或者不够贪婪,并且它们可能对单词边界和逗号等不敏感。Pandoc 占了大部分以及更多。
从命令行(--smart 参数开启智能引号):
pandoc --smart --standalone -o output.html input.html
..我知道命令行脚本可能符合也可能不符合 OP 对 使用 Javascript 的要求。 (相关:How to execute shell command in Javascript)
【讨论】:
以上是关于将“直引号”转换为“弯引号”的主要内容,如果未能解决你的问题,请参考以下文章
使用LaTeX'listing'包时,如何显示直引号而不是弯引号?