英語の句読点規則を適用する


11

ディクテーション作成アプリのコードを書くために雇われました。このアプリは、音声入力から音声入力を取得し、それを単語として解析し、画面に書き留めます。

経営陣はプロジェクトのパワーを本当に信用していません。残念ながら仕事をするのではなく、一日中じっと座ってゴルフをすることで知られています。適切にフォーマットされた文への句読点が散在した文。「適切にフォーマットされた」は以下で定義されます。

  1. Sentenceは入力の文字列です。Wordは、連続する非スペース文字のグループです。句読点は、最初の文字がである単語です^

  2. 単語の最初の文字が小文字ではない場合、単語は大文字になります(大文字の単語は正規表現に一致します/[^a-z].*/)。

  3. 文の最初の言葉は大文字にする必要があります。

  4. A ^COMMAはコンマ文字,であり、スペースが続きますが、前にはありません。aaa ^COMMA bbbになりaaa, bbbます。

  5. A ^COLONはのようなカンマです:

  6. A ^SEMICOLONはのようなカンマです;

  7. A ^PERIODはのようなカンマです.。aに続く単語は^PERIOD大文字にする必要があります。

  8. A ^BANGは次のような期間です!

  9. A ^DASHはダッシュ文字-であり、前後にスペースがあります。

  10. A ^HYPHENもダッシュ文字です-が、前後にスペースはありません。

  11. An ^EMDASHは、ハイフン(ダッシュではありません!)で、スペルがあります--

  12. アンは^OPENQUOTE引用符で"スペース以下の直前ではなく、を持っています。に続く単語は^OPENQUOTE大文字にする必要があります。の^OPENQUOTE前に句読点ではない単語がある場合は^COMMA、その単語との間にを追加し^OPENQUOTEます。^OPENQUOTE次の単語を大文字にする句読点がanの前にある場合、次の単語にスキップし^OPENQUOTEます。

  13. A ^CLOSEQUOTEは、,"後にスペースが続くが前にはない有向グラフです。場合^CLOSEQUOTEによって先行される^COMMA^PERIODまたは^BANG、句読点が消えていることを^CLOSEQUOTE綴られている,"."または!"それぞれ。句読点が消えて大文字が指定された場合、その大文字は引き続き次の使用可能な単語で発生する必要があります。

  14. 完全な最終結果の最初のスペースまたは末尾のスペースは削除する必要があり、行内の2つ以上のスペースの文字列はすべて単一のスペース文字に折りたたむ必要があります。

  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
    

これはコードゴルフです。最低スコアが勝ちます。1つの文字列引数の関数、またはSTDINから読み取りSTDOUTに書き込むプログラムを作成できます。


javascriptを使用する場合はどうなりますか?標準入力はありません。使用できますprompt()か?
ニカエル14年

@nicael OPは1つの文字列引数の使用に言及しているので、私のJSの例では、1つの引数を取る関数を作成し、その引数はSTDIN
Eric Lagergren 14年

1
「[あなたの言語はこちら]」という名前の
エソラン

回答:


4

JavaScript:653 611 547 514 487バイト

なんてことだ。ブレンダン・エイチこれはすみません。

PS:読みやすくするために空白を追加しましたが、許可されているすべての空白を削除すると、バイトカウントがリストされます。

理論的には私のようないくつかの部分を短くすることができ-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))

611 FF 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で正規表現をテストしましたが、太い矢印はサポートしていません。私は現在FFでそれをまっすぐにすることに取り組んでいますが、正規表現に「または」のように「および」演算子が実際にはないことは嫌です。@ edc65
エリックラガーグレン14年

@ edc65なので=>、動作させるには2を使用する必要があると思いますが、矢印を使用すると40バイト節約できます!
エリックラガーグレン14年

置換replaceをR = 'replace'に置換します... [R] ;-)
edc65 14年

ちょうどそれをやった:) 563 @ edc65になった
エリックラガーグレン14年

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 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.