应用英语标点规则


11

您已被聘请为听写应用程序编写一些代码,该应用程序从语音来源获取语音输入,将其解析为单词,然后将其写在屏幕上。

管理层并不真正相信您在项目中拥有如此强大的力量-不幸的是,您整天坐在那里闲逛,打高尔夫球,而不是去做工作,因此-他们只是给您执行一个非常简单的任务:将句点插入到正确格式化的句子中的句子,其中“正确格式化”的定义如下。

  1. 句子是输入字符串。单词是一组连续的非空格字符。标点符号是第一个字符为的单词^

  2. 如果单词的第一个字母不是小写字母(大写单词与regex匹配),则单词为大写/[^a-z].*/

  3. 句子的第一个字必须大写。

  4. A ^COMMA是逗号字符,,在其后但没有前有一个空格。aaa ^COMMA bbb成为aaa, bbb

  5. A ^COLON是看起来像的逗号:

  6. A ^SEMICOLON是看起来像的逗号;

  7. A ^PERIOD是看起来像的逗号.。后面的单词^PERIOD必须大写。

  8. A ^BANG是一个看起来像的时期!

  9. A ^DASH是破折号字符-,前后都有一个空格。

  10. A ^HYPHEN也是破折号,-但前后没有空格。

  11. An ^EMDASH是拼写的连字符(而不是破折号!)--

  12. An ^OPENQUOTE是一个引号字符",在其前面但后面没有空格。后面的单词^OPENQUOTE必须大写。如果在^OPENQUOTE之前加上非标点^COMMA词,请在该词和之间添加一个^OPENQUOTE。如果在^OPENQUOTE的前面加上使下一个单词大写的标点符号,则会跳过^OPENQUOTE到下一个单词。

  13. A ^CLOSEQUOTE是有向图,",其后跟但前无空格。如果^CLOSEQUOTE前面有一个^COMMA^PERIOD^BANG,即标点消失,^CLOSEQUOTE拼写,"."或者!"分别。如果消失的标点指定大写,则该大写仍必须出现在下一个可用单词上。

  14. 必须删除完整最终结果中的开头或结尾空格,并且一行中两个或多个空格的任何字符串都必须全部折叠成一个空格字符。

  15. 上面未涉及的任何情况(例如^COMMA ^COMMA^SEMICOLON ^CLOSEQUOTE^UNDEFINEDPUNCTUATION)都不会出现在格式正确的输入中,因此是不确定的行为。

开发团队会通知您以下内容:

  • 该项目以[您在这里的语言]语言编写,并且应尽可能短,以便在它是Android / iPhone应用程序时占用尽可能少的空间。您尝试解释这不是应用程序开发的工作原理,但他们不听。但是,嘿,真是巧合!您是[[您这里的语言]的出色高尔夫球手!

  • 该应用程序将没有任何Web访问权限,并且不会安装任何库来为您执行此格式设置。您可以说服团队领导允许您使用正则表达式库(如果您的语言存在),但是如果您认为需要的话。

  • 计划在应用程序的更高版本中支持正确使用双引号/单引号的嵌套引号,但现在不支持您正在使用的版本,因此不必担心。

  • 管理层是测试驱动开发的忠实拥护者,因此开发团队已经让一些不幸的键盘猴子为您的程序部分编写了一些测试:(添加了换行符以提高可读性,将它们视为空格)

    输入:

    hello ^COMMA   world ^BANG
    

    输出:

    Hello, world!
    

    输入:

    once upon a time ^COMMA there was a horse ^PERIOD that horse cost me $50
    ^PERIOD ^OPENQUOTE eat your stupid oats ^COMMA already ^BANG ^CLOSEQUOTE
    I told the horse ^PERIOD the horse neighed back ^OPENQUOTE no ^CLOSEQUOTE
    and died ^PERIOD THE END
    

    输出:

    Once upon a time, there was a horse. That horse cost me $50. "Eat your
    stupid oats, already!" I told the horse. The horse neighed back, "No,"
    and died. THE END
    

    输入:

    begin a ^PERIOD b ^COMMA c ^COLON d ^SEMICOLON e ^BANG f ^HYPHEN g ^DASH h
    ^EMDASH i ^OPENQUOTE j ^PERIOD ^OPENQUOTE k ^SEMICOLON ^OPENQUOTE l
    ^CLOSEQUOTE m ^BANG ^CLOSEQUOTE n ^PERIOD 0x6C6F6C end
    

    输出:

    Begin a. B, c: d; e! F-g - h--i, "j. "K; "l," m!" N. 0x6C6F6C end
    

这是代码高尔夫:最低分获胜。您可以编写一个字符串参数的函数,也可以编写从STDIN读取并写入STDOUT的程序。


如果我想使用JavaScript怎么办?没有标准输入。我可以使用prompt()吗?
nicael 2014年

@nicael OP提到使用一个字符串参数,因此对于我的JS示例,我刚刚制作了一个带有一个参数的函数,并假定该参数是类似于STDIN的单词字符串
Eric Lagergren 2014年

1
我想知道是否有esolang名为“ [您的语言在这里]”
Akangka '16

Answers:


4

JavaScript:653611547514487字节

天啊。布伦丹·艾希(Brendan Eich),对此我感到很抱歉。

PS:我添加了空格以提高可读性,但是删除所有允许的空格会导致列出的字节数。

从理论上讲,我可以将诸如之类的某些部分缩短-e--e-e,但是如果前一个单词以“ e”(或我决定使用的哪个单词)开头,或者后一个单词以字母“ e”开头,可能会引起问题。我想我可以使用ASCII字符。我会调查的。

仅限487 FF22 +

R = "replace", C = "charAt", U = "toUpperCase";
alert(a[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s)|(\-\e\-\s))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]())))

仅514 FF22 +

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((k, l, v, n, o, p, q, r, s) => v ? "." : n ? "!" : o ? "," : p ? ";" : q ? ":" : r ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, (t => t[C](0)[U]() + t.substr(1)))[R](/\"[a-z]/g, (u => u[C](0) + u[C](1)[U]()))
}(a))

仅547 FF22 +

alert(function(z) {
    R = "replace", C = "charAt", U = "toUpperCase";
    return z[R](/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((m, _, a, b, c, d, e, f, g, h, i, j) => a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" '))[R](/\s+((\.)|(\!)|(\,)|(\;)|(\:)|(\-\h\-\s+)|(\-\e\-\s+))/g, ((xx, __, k, l, m, n, o, p, q) => k ? "." : l ? "!" : m ? "," : n ? ";" : o ? ":" : p ? "-" : "--"))[R](/[^!,"'.]\"\s/g, '"')[R](/.+?[\.\?\!](\s+|$)/g, function(r) {
        return r[C](0)[U]() + r.substr(1)
    })[R](/\"[a-z]/g, function(s) {
        return s[C](0) + s[C](1)[U]()
    })
}(a))

仅限611FF 22+

alert(function(c) {
    return c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG)|(DASH)|(HYPHEN)|(EMDASH)|(OPENQUOTE)|(CLOSEQUOTE))/g, ((x, _, a, b, c, d, e, f, g, h, i) = > a ? "," : b ? ";" : c ? ":" : d ? "." : e ? "!" : f ? "-" : g ? "-h-" : h ? "-e-" : i ? ' "' : '" ')).replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\-\h\-\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s+|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

653跨浏览器

alert(function(c) {
    return c.replace(/\^COMMA/g, ",").replace(/\^SEMICOLON/g, ";").replace(/\^COLON/g, ":").replace(/\^PERIOD/g, ".").replace(/\^BANG/g, "!").replace(/\^DASH/g, "-").replace(/\^HYPHEN/g, "h-h").replace(/\^EMDASH/g, "-e-").replace(/\^OPENQUOTE/g, ' "').replace(/\^CLOSEQUOTE/g, '" ').replace(/\s+\./g, ".").replace(/\s+\!/g, "!").replace(/\s+\,/g, ",").replace(/\s+\;/g, ";").replace(/\s+\:/g, ":").replace(/\s\h\-\h\s/g, "-").replace(/[^!,"'.]\"\s/g, '"').replace(/\s+\-\e-\s+/g, "--").replace(/.+?[\.\?\!](\s|$)/g, function(b) {
        return b.charAt(0).toUpperCase() + b.substr(1)
    }).replace(/\"[a-z]/g, function(b) {
        return b.charAt(0) + b.charAt(1).toUpperCase()
    })
}(a))

这个怎么运作:

https://gist.github.com/ericlagergren/1a61b5d772ae49ab3aea

JSFiddle(用于653字节跨浏览器解决方案)

JSFiddle适用于595 FF 22+ 解决方案)

JSFiddle适用于547 FF 22+ 解决方案)

JSFiddle适用于514 FF 22+ 解决方案)

JSFiddle适用于487 FF 22+ 解决方案)

这是我第一次必须编写使用多个正则表达式的JS,通常我的正则表达式是预定义的。

我将继续尽量减少字节数。


您可以像这样缩短您的第一次替换:c.replace(/\^((COMMA)|(SEMICOLON)|(COLON)|(PERIOD)|(BANG))/g,(m,_,a,b,c,d,e)=>a?',':b?';':c?':':d?'.':'!'))...依此类推。箭头sintax很短,但即使是“函数”也应保存相同的字符
edc65

你是对的。我用Chrome测试了regexp,它不支持粗箭头。我正在努力通过FF进行理顺,但是我讨厌正则表达式实际上并没有像它们执行“或”那样真正具有“和”运算符。@ edc65
Eric Lagergren

@ edc65,所以我想必须使用两个=>s才能使其正常工作,但是使用箭头可以节省40个字节!
埃里克·拉格伦2014年

替换替换为R ='replace'... [R] ;-)
edc65 2014年

只是做到了:)降至563 @ edc65
Eric Lagergren

1

PHP,412字节

(为了清楚起见,此处未进行高尔夫展示有关高尔夫版本请参见ideone。)

PHP的preg_replace()函数将接受数组参数,这在这里非常有用。我认为以下代码可以完成所有必需的工作。它至少通过了所有测试用例。

function x($s) {
    $r='preg_replace';
    $s=$r('/ +/',' ',$s);
    $s=$r(array('/ \^COMMA/','/ \^COLON/','/ \^SEMICOLON/','/ \^PERIOD/','/ \^BANG/',
                '/\^DASH/','/ \^HYPHEN /','/ \^EMDASH /','/\^OPENQUOTE /','/ \^CLOSEQUOTE/'),
          array(',',':',';','.','!','-','-','--','"',',"'),
          $s);
    $s=$r('/(^\W*\w|([\.!]| ")\W+\w)/e','strtoupper("$0")',$s);
    $s=$r('/([,\.!]),/','\1',$s);
    $s=$r('/(\w)( "\w)/e','"$1,".strtoupper("$2")',$s);
    echo $s;
}

完美的作品!ideone.com/AYtTiI尽管我感到困惑的是我们应该在引号前加上逗号吗?因为从语法上讲,引号不仅用于语音,而且仅语音在引号前具有逗号。我假设既然有一个^ COMMA,我们就让用户输入逗号
Eric Lagergren 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.