7

Google のエイプリルフールのモールス信号 gmail のジョークを見た後、javascript でリアルタイムのモールス信号コンバーターを作成してみようと思いました。

正規表現と置換を使用して、モールス信号を文字に変更しています。例えば:

.replace(/.- /g, "a").replace(/.-. /g, "r")

私が抱えている問題は.-.、「r」を入力すると、.-最初に表示されるため「a」が表示されることです。完全一致のみを置き換えるにはどうすればよいですか?

更新され、動作しています!! 私を助けてくれたすべての人に感謝します

http://jsfiddle.net/EnigmaMaster/sPDHL/32/ - 私のオリジナルのコード

http://jsfiddle.net/EnigmaMaster/LDKKE/6/ - ショーン・チンによって書き直されました

http://jsfiddle.net/EnigmaMaster/y9A4Y/2/ - Matthias Tylkowski によって書き直されました

誰かがこのプログラムを書く他の方法を持っているなら、JsFiddleを投稿してください

他にどのようにこれを行うことができるかを知りたいです

4

9 に答える 9

3

それを行う別の方法は、二分探索を使用することです。

ここに画像の説明を入力

二分検索テーブルのグラフィカルな表現: ユーザーは、文字が終了するまで、すべてのドットで左に分岐し、すべてのダッシュで右に分岐します。

于 2013-03-18T04:13:39.513 に答える
3

あなたの質問は、興味深い事実を浮き彫りにしています。モールス信号はプレフィックス コードではありません。そのため、コード記号を区切るために、スペースやカンマなどのセパレータが必要です。

スペースを使用することにしたようです。それで問題ありません。

そうは言っても、正規表現に欠けているのは、ドット記号のエスケープです(の/\.- /代わりに使用します/.- /

于 2012-04-18T16:41:19.967 に答える
1

正規表現では、ドットは任意の文字と一致し、適切なスケープなしで使用しているようです。

/./  // this will match any character
/\./ // this will match a dot (".") character
于 2012-04-18T16:42:42.493 に答える
1

他の回答は、あなたの例が機能しなかった理由をすでにカバーしているので、繰り返すことは控えます。

ただし、各コードを区切るために既にスペースを使用しているため、簡単な解決策は.split()、入力テキストを個々のユニットにセグメント化してから、コードを 1 対 1 でマッピングすることです。文字。これは、正規表現の置き換えを繰り返すよりもはるかに効率的であり、エラーが発生しにくくなります。

例えば:

var morse = {  // use object as a map
    '.-': 'a', 
    '-...': 'b', 
    '-.-.': 'c', 
    // .... the rest ...
};

function translate_morse(code) {  // given code, return matching char
    return (typeof morse[code] === "undefined") ? "" : morse[code];
    // if the var is not found, the code is unknown/invalid. Here we 
    // simply ignore it but you could print out the code verbatim and use
    // different font styles to indicate an erroneous code
}

// example usage
translated = code_text.split(" ").map(translate_morse).join("");

これが実際の例です: http://jsfiddle.net/KGVAm/1/

ps 私は自由にコードと動作を微調整しました。つまり、他の文字の入力を無効にしましたが、バックスケープで修正できるようにしました。

于 2012-04-19T09:05:55.490 に答える
1

一度に 1 つのモールス文字を処理する場合は、最も長いシーケンスから始めて、短いシーケンスに下げていきます。

于 2012-04-18T16:34:11.173 に答える
1

ルールに優先順位を付け、最初に長いフレーズの置換を適用する必要があります。

.replace(/\.-\./g,'r')// longer
.replace(/\.-/g,'a')// shorter

辞書を作成し、パターンの長さで並べ替えてから、文字列を置き換えることをお勧めします。

var str = '.-.-.';
var dictionary = [
    ['a', '\.-'],
    ['r', '\.-\.']
    // ... and so on
];
dictionary
    .sort(function(a,b){
        return a[1] > b[1];
    })
    .forEach(function(el,i){
         str = str.replace(new RegExp(el[1],'g'),el[0]);
    });

かっこがないのは残念ですが、私の電話では見つけられないようです。

更新: 正規表現で使用されているドットをエスケープしました。そもそもそれを見逃していました。 update2 : 括弧を追加しました:)辞書でエスケープされていないドットを使用して、その場でエスケープできます:

 var dictionary = [
    ['a', '.-'],
    ['r', '.-.']
];
dictionary
    .sort(function(a,b){
        return a[1] > b[1];
    })
    .forEach(function(el,i){
         str = str.replace(new RegExp(el[1].replace(/([^\]\.)/g,'$1\.'),'g'),el[0]);
    });
于 2012-04-18T16:34:37.523 に答える
1

「。」をエスケープする必要があります。文字:

/\.- /

それ以外の

/.- /

言い換えると。正規表現では「.」任意の文字に一致します。

于 2012-04-18T16:34:46.710 に答える
0

ここでの秘訣は、誰かが入力した文字列をチャンクに分割することだと思います。"." の各シーケンスの後にはスペースが必要です。と "-"。次に、その配列を実行して、すべてのエントリを対応する文字に置き換えることができます。私ならスイッチを使います。最後に、配列を文字列として結合して表示します。

于 2012-04-18T16:47:07.583 に答える