【问题标题】:How can I split a long continuous string into an array of the words it contains?如何将一个长的连续字符串拆分为它包含的单词数组?
【发布时间】:2022-01-08 02:38:14
【问题描述】:

我有一个长的连续字符串,看起来像这样:

let myString = "onetwothreefourfivesixseveneightnineteneleventwelvethirteenfourteen";

它没有任何可轻松定位的分隔符。
那么我怎样才能迭代它并拆分单词,所以它最终会像:

splitString = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"];

最好使用 JavaScript。

【问题讨论】:

  • 你事先知道所有可能的单词吗?
  • C++ 怎么样?
  • @CBroe 是的,我事先知道所有可能的词
  • @Andam 我知道,但我对编程也比较陌生,并且正在努力学习。
  • @StianS 是的,如果您有程序要查找的所有可能的单词(例如在数组中),您可以。

标签: javascript arrays string split


【解决方案1】:

这里的问题是您提到的缺少分隔符 - 这使得软件无法知道单词的开始和结束位置。

鉴于你知道会出现的单词,我的技巧是这样的:

注意:这并没有考虑到单词重叠的可能性,并假设没有一个单词是其他单词的可能子集...

  1. 迭代已知单词
  2. 搜索 (indexOf) 每个已知单词的字符串并记下它在字符串中的位置
  3. 按索引值对值进行排序
  4. 使用找到的顺序中包含的值生成一个数组

/**
 * This assumes that:
 *  - Input words are not subsets of other input words
 */

// Find all indices of the input word in the input String
function findAll(inputString, inputWord) {
    const indices = [];
    let index = 0;
    while (index < inputString.length) {
        index = inputString.indexOf(inputWord, index);
        if (index == -1) break; // -1 means not found so we break here
        indices.push({ index, word: inputWord });
        index += inputWord.length;
    }
    return indices;
}

// Split the words into an array of Objects holding their positions and values
function splitWords(inputString, inputWords) {
    // For holding the results
    let results = [];
    // Loop the input words
    for (const inputWord of inputWords) {
        // Find the indices and concat to the results array
        results = results.concat(findAll(inputString, inputWord));
    }
    return results;
}

// Sort the words and return just an array of Strings
const orderWords = (inputArr) => inputArr.sort((a, b) => a.index - b.index).map(input => input.word);

/**
 * Usage like so:
 */
const myString = 'onetwothreefourfivesixseveneightnineteneleventwelvethirteenfourteen';
const inputWords = ["one", "two", "three","four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen"];

const result = splitWords(myString, inputWords);
const ordered = orderWords(result);

console.dir(ordered);

/**
 * Result:
    [
    'one',      'two',
    'three',    'four',
    'five',     'six',
    'seven',    'eight',
    'nine',     'ten',
    'eleven',   'twelve',
    'thirteen', 'four',
    'fourteen'
    ]
 */

【讨论】:

  • 谢谢,刚刚试了一下,效果很好,和@andam 的解决方案一样,希望我能将两个帖子标记为同样好。
  • 很高兴这对您有用 - 尽管请注意这会在您的输入单词中提取重复项(例如“十四”中的“四”。
  • 我翻转了数组来解决这个问题。从最高的数字开始,按我的顺序排列
【解决方案2】:

如果您在 cmets 中说您知道预期的单词,则创建这些单词的数组并循环遍历您的字符串以查找这些单词

注意下面的代码考虑了匹配单词的长度,以便您可以找到诸如one hundred eighty five之类的单词,否则循环在找到one时停止

您可以阅读代码中的 cmets 以更好地理解它

// your string
var myString =
"onetwothreefourfivesixseveneightnineteneleventwelvethirteenfourteentwentyfiveonehundredeightyfiveeightyfive";

// the list of expected words
var possibleWords = 
[ 
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "twenty five",
    "one hundred eighty five",
    "eighty five",
];


function separateString(mergedString, possibleWords) {
     // the resulted array that has all the splited words
    var result = [];
    
    // buffer to temporary store the string and match it with the expected words array
    var buffer = ""; 

    // The word that has been matched in buffer with possible word in expected words array
    var matchedWord = "";
    
    // Index if the matched word
    var matchedWordLastIndex = -1;

    // Converting your string into array so we can access it by index letter by letter
    var splitedString = mergedString.split("");

    // For every letter in your string
    for (var stringIndex = 0; stringIndex < splitedString.length; stringIndex++) 
    {
        // Resetting the variables 
        matchedWord = "";
        buffer = "";
        matchedWordLastIndex = -1;
        
        // Look a head from current string index to the end of your string and find every word that matches with expected words
        for ( var lookAhead = stringIndex; lookAhead < splitedString.length; lookAhead++) 
        {
            // Append letters with each iteration of look ahead with the buffer so we can make words from it
            buffer += splitedString[lookAhead];

            // loop through expected words to find a match with buffer
            for (var i = 0; i < possibleWords.length; i++) {

                // if buffer is equal to a word in expected words array: .replace(/ /g, '') removes space if the words inside expected array of words have space such as twenty five to twentyfive
                if (buffer == possibleWords[i].replace(/ /g, '')) 
                {
                    // check if the found word has more letters than the previouse matched word so we can find words like one hundred eighty five otherwise it will just find one and stops
                    if(matchedWord.length < buffer.length)
                    {
                        // if the word has more letters then put the word into matched word and store the look ahead index into matchedWordLastIndex
                        matchedWord = possibleWords[i];
                        matchedWordLastIndex = lookAhead;
                    }
                }
            }
        }


        // if a word has been found
        if(matchedWord.length > 0){
            // make starting index same as look ahead index since last word found ended there
            stringIndex = matchedWordLastIndex;
            // put the found word into result array
            result.push(matchedWord);
        }
    }
    
    return result;
}

console.log(separateString(myString, possibleWords));

【讨论】:

  • 成功了!如果我可以将你们两个标记为最佳答案,我会的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 2020-10-19
  • 1970-01-01
相关资源
最近更新 更多