将“直引号”转换为“卷曲引号”

Converting ″Straight Quotes″ to “Curly Quotes”

提问人:BlueVoid 提问时间:2/5/2010 最后编辑:tchristBlueVoid 更新时间:2/27/2016 访问量:12898

问:

我有一个使用基于 Javascript 的规则引擎的应用程序。我需要一种方法将常规直引号转换为卷曲(或智能)引号。只做一个 for 很容易,只是这只会插入一个大括号的情况。string.replace["]

我能想到的最好的方法是用左卷曲的引号替换第一次出现的引号,用左卷曲替换其他引号,其余的用右卷曲替换。

有没有办法使用 Javascript 实现这一点?

JavaScript 则表达 智能报价

评论

1赞 Nate C-K 2/5/2010
您可能想稍微玩一下文字处理器,看看它使用什么规则来确定使用哪些引号。据我所知,它们是基于引用的上下文,而不是配对。
0赞 Dave Jarvis 7/10/2022
这回答了你的问题吗?将直引号转换为大引号的想法

答:

4赞 Luca Matteis 2/5/2010 #1
'foo "foo bar" "bar"'.replace(/"([-a-zA-Z0-9 ]+)"/g, function(wholeMatch, m1){
    return "“" + m1 + "”";
});

评论

1赞 SLaks 2/5/2010
这并不能回答这个问题。
1赞 Anon. 2/5/2010
它将如何处理?"John was 6' 4""
1赞 Earlz 2/5/2010
@Anon,如果没有足够的智慧来知道英寸和英尺是什么,任何程序将如何处理它?
2赞 Anon. 2/5/2010
我见过的东西通常会以正确的方向卷曲引号,但也会以相同的方式卷曲英寸标记。它做的是卷曲英寸标记,然后以与它应该做的事情相反的方式卷曲每个其他引号。
1赞 Luca Matteis 2/5/2010
@Anon:那么也许你应该发布一个解决方案。
15赞 Nicole 2/5/2010 #2

您可以用左引号替换单词字符前面的所有字符,用右引号替换单词字符后面的所有字符。

str = str.replace(/"(?=\w|$)/g, "“");
str = str.replace(/(?<=\w|^)"/g, "&#8221;"); // IF the language supports look-
                                             // behind. Otherwise, see below.

正如下面的评论所指出的,这不考虑标点符号,但很容易:

/(?<=[\w,.?!\)]|^)"/g

[编辑:] 对于不支持后视的语言,比如 Javascript,只要你先替换所有前置的语言,你就有两个选择:

str = str.replace(/"/g, "&#8221;"); // Replace the rest with right curly quotes
// or...
str = str.replace(/\b"/g, "&#8221;"); // Replace any quotes after a word
                                      // boundary with right curly quotes

(我保留了上面的原始解决方案,以防这对使用支持后视的语言的人有所帮助)

评论

0赞 Anon. 2/5/2010
+1 表示实际回答问题。尽管用户应该考虑到它并非在所有情况下都是完美的 - 例如,指示英尺和英寸的破折号。
0赞 Pointy 2/5/2010
...或结束引文的标点符号。
0赞 BlueVoid 2/5/2010
谢谢!这就是我一直在寻找的。请注意,复制代码完全给了我一个错误。“?<=”部分已更改为“?=”。此外,我必须从结尾大小写中删除引号字符才能正确匹配。代码: s = s.replace(/“(?=\w|$)/g, ”“”);s = s.replace(/(?=[\w,.?!\-“)]|^)”/g, “”“);
0赞 Nicole 2/5/2010
@BlueVoid - 你对这个错误是正确的,我发现了这一点,并在你评论时更新了我的答案:)小心你的代码 - 是一个前瞻,它匹配,因为它向前看并看到引号,它位于你的字符类中。我会在我编辑的答案中使用第一个“替代”解决方案——只需在替换卷引号大引号替换所有引号即可。?=
0赞 BlueVoid 2/5/2010
@Renesis 好点子。无论如何,这简化了事情。它工作得很好。
0赞 Pointy 2/5/2010 #3

我不认为这样的事情通常很容易,因为你必须准确解释内容中每个双引号字符的含义。也就是说,我要做的是收集所有我感兴趣的文本节点,然后检查并跟踪每个双引号实例的“开/关”(或“奇数/偶数”;随便什么)性质。然后,您可以知道要使用哪个替换实体。

5赞 Steven Dee 3/25/2010 #4

您可能想看看 Pandoc 是做什么的——显然,有了这个选项,它可以在所有情况下正确处理引号(包括例如 'tis 和 'twere)。--smart

我最近写了一个 Javascript 排版美化引擎,除其他外,它还可以替换引号;我最终基本上使用了 Renesis 建议的算法,但目前有一个失败的测试正在等待更智能的解决方案。

如果你有兴趣编写我的代码(和/或根据你所做的工作提交补丁),请查看:jsPrettify。 做你要找的。如果你不想处理 Closure 依赖项,有一个旧版本可以单独运行——它甚至可以在 Rhino 中工作。jsprettify.prettifyStr

评论

0赞 Paulb 2/27/2016
Pandoc 加 1。我尝试尽可能使用成熟且经过测试的工具,而不是烘焙自己的正则表达式。手工构建的正则表达式不会过于贪婪,或者不够贪婪,它们可能对单词边界和逗号等不敏感。Pandoc 占了大部分,甚至更多。
3赞 Jordan 11/29/2010 #5

以下只是通过交替更改每个引号(但是,这个特定示例会省略孤立的引号)。

str.replace(/\"([^\"]*)\"/gi,"&#8220;$1&#8221;");

只要您正在纹理化的文本没有因双引号使用不当而搞砸,就可以完美地工作。在英语中,引号从不嵌套。

评论

4赞 tchrist 11/29/2010
在英语中,有一种合法的情况,这条规则被打破了。当你有连续的段落代表同一位演讲者引用的演讲时,必须以适当的引号(单引号、双引号、单引号+双引号、双引号+单引号等)开头,但除了同一发言者的最后一段外,一个段落会省略结束引号。
0赞 David Lee 12/13/2014 #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。

0赞 Paulb 2/27/2016 #7

为后代发布。

按照 @Steven Dee 的建议,我去了潘多克

我尝试尽可能使用成熟且经过测试的工具,而不是烘焙自己的正则表达式。手工构建的正则表达式可能过于贪婪,或者不够贪婪,并且它们可能对单词边界和逗号等不敏感。Pandoc 占了大部分,甚至更多。

从命令行(--smart 参数打开智能引号):

pandoc --smart --standalone -o output.html input.html

..我知道命令行脚本可能适合也可能不符合 OP 使用 Javascript 的要求。(相关:如何在 Javascript 中执行 shell 命令)