用字母在字母表中的位置替换字母 - 正则表达式

8

这个挑战的描述是将一个字符串中的字母替换为该字母在字母表中的位置,从1开始计数。要求您跳过所有非字符,包括空格。

function alphabetPosition(text) {
  var result = [];
  var alphabet = ["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"]
  text = text.replace(/\W*\d+/g, '').toLowerCase().split('');
  for (var i = 0; i < text.length; i++) 
    result.push(alphabet.indexOf(text[i]) + 1);
  return result.join(' ');
}

我的问题是在进行随机测试时,输入会包含数字和非单词字符,但正则表达式无法识别。输入为n8_ovuu&,输出/错误是期望值为:“14 15 22 21 21”,实际得到的是:“14 0 15 22 21 21 0”
问题出在正则表达式上,但我无法解决它。如果您有任何想法,我会非常感谢您的帮助!
6个回答

12
在你的循环中添加一个条件:
替换为:
for (var i = 0; i < text.length; i++) 
  result.push(alphabet.indexOf(text[i]) + 1);

使用:

for (var i = 0; i < text.length; i++) {
  var j = alphabet.indexOf(text[i]) + 1;
  if (j) result.push(j);
}

请注意,您可以将字母表定义为字符串而不是数组,而上述循环不需要做任何更改:

var alphabet = 'abcdefghijklmnopqrstuvwxyz';

无需正则表达式的函数式编程解决方案

这是一个使用ES6代码解决方案,通过链式调用多个方法,在一个return语句中返回结果:

function alphabetPosition(text) {
  return text.toLowerCase().split('')
        .filter( c => c >= 'a' & c <= 'z' )
        .map( c => c.charCodeAt(0) - 'a'.charCodeAt(0) + 1)
        .join(' ');
}

console.log(alphabetPosition('n8_ovuu&'));

使用正则表达式的函数式编程解决方案

function alphabetPosition(text) {
  return text.toLowerCase().replace(/[^a-z]/g, '')
        .replace(/./g, ([c]) => ' ' + (c.charCodeAt(0) - 'a'.charCodeAt(0) + 1))
        .substr(1);
}

console.log(alphabetPosition('n8_ovuu&'));


那很好,这也让我摆脱了正则表达式,这对我来说是一种解脱! - Jon Langel
实际上,您还可以简化字母表变量。它可以只是一个字符串,因为它支持indexOf就像数组一样。 - trincot
为了好玩,我也添加了一个完全不同的解决方案。 - trincot

3
你得到零是因为一些字符(比如_&)与字母表不匹配。当.indexOf()找不到匹配项时,它会返回-1。然后你会加上+ 1,使其变为零。
你可以将这些字符添加到字母表中,或者通过添加一个if子句来忽略它们。
for (var i = 0; i < text.length; i++) {
    var index = alphabet.indexOf(text[i]);
    if (index > -1) {
        result.push(index + 1);
    }
}

为了让你的正则表达式过滤非字母字符,将\W替换为明确的反转字符范围[^a-zA-Z]

console.log("abc_def".replace(/[^a-zA-Z]/, ''));


我看到了,我正在尝试弄清楚如何使用 text.replace + Regex 来识别那些非单词字符并替换它们。 - Jon Langel
请更新您的问题并澄清正则表达式无法工作。我已经更新了我的答案,解释如何修复正则表达式。 - Soviut
更新了标题和正文。感谢解释正则表达式!非常感激! - Jon Langel

2
这个方法行之有效,而且非常简洁:

const data = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"£$%^&*()';

const result = data.toLowerCase().match(/[a-z]/g).map(c => c.charCodeAt(0) - 96).join(' ');

console.log(result);


1
你可以使用一个对象来表示字母的索引。如果找不到任何一个,取默认值。

function alphabetPosition(text) {
    var alphabet = ["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"],
        object = {};

    alphabet.forEach(function (a, i) {
        object[a] = i + 1;
    });
    return text.replace(/\W*\d+/g, '').toLowerCase().split('').map(function (a) {
        return object[a] || 0;
    }).join(' ');
}

console.log(alphabetPosition('n8_ovuu&'));


1

嘿,这对我有用。

const alphabetPosition = (text) => {
    // First isolate the characters in the string using split method, and then map them.
    const result = text.split('').map(a => parseInt(a, 36) - 9)
        .filter(a => a >= +1).join(' ')

    console.log(result)
  }

alphabetPosition(text)

0
import string

def alphabet_position(text):
  text = text.lower
  result = ""
  for x in text():
     if x.isalpha():
        result = result + str(string.ascii_lowercase.index(x) + 1) + " "
    else:
        pass
  result = result.strip()
  return result

请勿直接粘贴代码,而是在简要解释后再进行粘贴。 - ORHAN ERDAY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接