7

在看到谷歌关于 gmail 莫尔斯电码的愚人节笑话后,我想我会尝试在 javascript 中创建一个实时莫尔斯电码转换器。

我正在使用正则表达式和替换将莫尔斯电码更改为字符。例如:

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

我遇到的问题是,当我输入.-.“r”时,它会给我一个“a”,因为它.-首先看到。我怎样才能让它只替换完全匹配?

更新和工作!感谢每一位帮助过我的人

http://jsfiddle.net/EnigmaMaster/sPDHL/32/ - 我的原始代码

http://jsfiddle.net/EnigmaMaster/LDKKE/6/ - 由 Shawn Chin 重写

http://jsfiddle.net/EnigmaMaster/y9A4Y/2/ - 由 Matthias Tylkowski 重写

如果有人有其他编写此程序的方法,请发布JsFiddle

我很想看看还能怎么做

4

9 回答 9

3

您的问题突出了一个有趣的事实:摩尔斯电码不是前缀码。因此,您需要某种分隔符(空格、逗号等)来分隔代码符号。

您似乎已决定使用空格,这很好。

话虽这么说,您的正则表达式中缺少的是点符号的转义(使用/\.- /而不是/.- /

于 2012-04-18T16:41:19.967 回答
3

另一种方法是使用二分搜索。

在此处输入图像描述

二分搜索表的图形表示:用户在每个点处向左分支,在每个破折号处向右分支,直到字符完成。

于 2013-03-18T04:13:39.513 回答
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 回答
1

在正则表达式中,点匹配任何字符,并且您似乎在没有适当的转义的情况下使用它:

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

其他答案已经涵盖了您的示例不起作用的原因,因此我将避免重复它们。

但是,我可以建议,由于您已经使用空格来分隔每个代码,一个直接的解决方案是做一个简单.split()的将输入文本分割成单独的单元,然后简单地做一个一对一的代码映射到字符。这将比重复的正则表达式替换更有效,并且更不容易出错。

例如:

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 我冒昧地稍微调整了代码和行为,即禁用其他字符的输入,但允许使用 backscape 进行更正。

于 2012-04-19T09:05:55.490 回答
0

我认为这里的技巧是将某人键入的字符串拆分为块。每个“.”序列之后应该有一个空格。和 ”-”。然后您可以运行该数组并将每个条目替换为相应的字母。我会用一个开关。最后,您将数组作为字符串连接在一起并显示它。

于 2012-04-18T16:47:07.583 回答
0

对于那些正在寻找整个翻译的人:

这是一个演示,这里是整个代码

var morseCode = {
    '.-': 'a',
    '-...': 'b',
    '-.-.': 'c',
    '-..': 'd',
    '.': 'e',
    '..-.': 'f',
    '--.': 'g',
    '....': 'h',
    '..': 'i',
    '.---': 'j',
    '-.-': 'k',
    '.-..': 'l',
    '--': 'm',
    '-.': 'n',
    '---': 'o',
    '.--.': 'p',
    '--.-': 'q',
    '.-.': 'r',
    '...': 's',
    '-': 't',
    '..-': 'u',
    '...-': 'v',
    '.--': 'w',
    '-..-': 'x',
    '-.--': 'y',
    '--..': 'z',
    '-----': '0',
    '.----': '1',
    '..---': '2',
    '...--': '3',
    '....-': '4',
    '.....': '5',
    '-....': '6',
    '--...': '7',
    '---..': '8',
    '----.': '9',
    '.--.-': 'à',
    '.--.-': 'å',
    '.-.-': 'ä',
    '----': 'ch',
    '.-..-': 'è',
    '..-..': 'é',
    '---.': 'ö',
    '..--': 'ü',
    '...--..': 'ß',
    '--.--': 'ñ',
    '.-.-.-': '.',
    '--..--': ',',
    '---...': ':',
    '-.-.-.': ';',
    '..--..': '?',
    '-....-': '-',
    '..--.-': '_',
    '-.--.': '(',
    '-.--.-': ')',
    '.----.': '\'',
    '-...-': '=',
    '.-.-.': '+',
    '-..-.': '/',
    '.--.-.': '@'
};
于 2016-07-29T13:16:49.317 回答