假設我在一個字串中有一個或兩個句子,并且我有一個單詞陣列。我需要在字串中找到陣列中兩個或多個單詞彼此相鄰的任何位置。
例子:
字:['cat','dog','and','the']
細繩:There is a dog and cat over there. The cat likes the dog.
結果:['dog and cat','the dog','the cat']
我能夠做到這一點的唯一方法是手動指定可能的組合,但最多只能使用 3 個單詞,因為它會很快變長。
uj5u.com熱心網友回復:
您可以使用兩個指標來遍歷陣列,以跟蹤包含在words陣列中的每個單詞序列的開頭和結尾。這里首先將字串轉換為洗掉標點符號的小寫單詞陣列(您需要擴展要洗掉的字符)。
const
words = ['cat', 'dog', 'and', 'the'],
string = 'There is a dog and cat over there. The cat likes the dog.',
expected = ['dog and cat', 'the dog', 'the cat']
let
stringArray = string.toLowerCase().replace(/[.,]/g, '').split(' '),
start = 0, end = 0, result = [];
while (start < stringArray.length) {
if (words.includes(stringArray[start])) {
end = start 1;
while (words.includes(stringArray[end])) {
end
}
if (end - start >= 2) {
result.push(stringArray.slice(start, end).join(' '));
}
start = end;
}
start
}
console.log(result)
uj5u.com熱心網友回復:
我會用兩個減少來做到這一點:一個通過在陣列中累積它們來對目標集中的連續單詞進行分組,另一個拒絕空陣列(運行結束)并加入連續的集合......
const words = ['cat','dog','and','the'];
const wordSet = new Set(words); // optional for O(1) lookup
const string = 'There is a dog and cat over there. The cat likes the dog.';
const tokens = string.split(/[ .] /).map(t => t.toLowerCase()); // split for space and periods, force lower case
const result = tokens
.reduce((acc, word) => {
if (wordSet.has(word)) acc[acc.length-1].push(word);
else acc.push([]);
return acc;
}, [[]])
.reduce((acc, run) => {
if (run.length) acc.push(run.join(' '));
return acc;
}, []);
console.log(result);
uj5u.com熱心網友回復:
這個問題可以通過“遍歷”句子來解決,從每個單詞開始并繼續每次遍歷,直到句子中的單詞不再出現在陣列中。
例如,第一次迭代將從句子的第一個單詞開始,并檢查它是否在陣列中。如果不在陣列中,則從第二個單詞重新開始。如果單詞存在,檢查下一個,如果它不在陣列中,則結束,如果在,則繼續。
兩個while回圈允許這樣做。非字母字符(例如標點符號)在使用regex.replace陳述句的存在測驗中被洗掉,而大寫字母被更改為小寫以進行比較:
sentenceWordArray[position].toLowerCase().replace(/[^a-z] /g, '')
如果位置超過句子單詞陣列的長度,內部回圈中需要一個break陳述句while來防止越界錯誤。
作業片段:
const words = ['cat','dog','and','the'];
const sentence = "There is a dog and cat over there. The cat likes the dog."
function matchWordRuns(sentence, dictionary) {
const sentenceWordArray = sentence.split(" ");
const results = [];
let position = 0;
const currentSearch = [];
while (position < sentenceWordArray.length) {
while (dictionary.indexOf(sentenceWordArray[position].toLowerCase().replace(/[^a-z] /g, '')) > -1){
currentSearch.push(sentenceWordArray[position].toLowerCase().replace(/[^a-z] /g, ''));
position ;
if (position>=sentenceWordArray.length) {
break;
}
} // end while word matched;
if (currentSearch.length>0) {
results.push(currentSearch.join(" "));
} // end if;
position ;
currentSearch.length=0; // empty array;
} // end while, search over;
return results;
} // end function;
console.log(matchWordRuns(sentence, words));
/*
result:
[
"dog and cat",
"the cat",
"the dog"
]
*/
uj5u.com熱心網友回復:
與 pilchard 的想法相同,但有一些改進:
使用帶有 Unicode 字符類的正則運算式來知道什么是“字母”,以及句子在哪里結束——因此,我們不需要明確列出標點符號,它應該適用于任何語言(例如
"日本語!",沒有".",也不匹配[a-z])結果是由原始字串的子字串制成的,因此它保留了大小寫和中間標點符號(這可能是也可能不是 OP 想要的;如果需要,再次通過
.toLowerCaseand傳遞它.replace)Set為了效率(假設string并且words足夠長以使其值得)生成器功能更靈活,只是因為我不經常看到它們:P
分別處理句子,所以它不會檢測到
"cat. The dog"
const words = ['cat','dog','and','the'];
const string = "There is a dog and cat over there. The cat likes the dog.";
function* findConsecutive(words, string) {
const wordSet = new Set(words.map(word => word.toLowerCase()));
const sentences = string.split(/\s*\p{Sentence_Terminal} \s*/u);
for (const sentence of sentences) {
let start = null, end;
const re = /\p{Letter} /gu;
while ((match = re.exec(sentence)) !== null) {
if (wordSet.has(match[0].toLowerCase())) {
start ??= match.index;
end = match.index match[0].length;
} else if (start !== null) {
yield sentence.substring(start, end);
start = null;
}
}
if (start !== null) {
yield sentence.substring(start, end);
}
}
}
console.log([...findConsecutive(words, string)]);
uj5u.com熱心網友回復:
這也適用于極端情況,即句子結尾和新句子開頭之間有 2 個連續單詞。like"A cat. The watcher"將不匹配,因為從技術上講,它們不是連續的單詞。它們之間有一個點。
該代碼將點視為“單詞”,首先洗掉文本中的點,然后在兩邊重新插入一個空格,如" . ". 因此,點充當句子之間的“連接詞”。這消除了對極端情況的特殊處理,因為在 2 個單詞之間有一個點,意味著它們永遠不會匹配為 2 個連續的單詞。然后文本洗掉任何多余的空格,并將文本拆分為單詞:
const words = ['cat', 'dog', 'and', 'the']
const text = 'There is a dog and cat over there. A cat. The cat likes the dog.'
const xs = text.toLowerCase().replace(/\./g," . ").replace(/ (?= )/g,'').split(' ')
var result = []
var matched = []
xs.forEach(x => {
if (words.includes(x))
matched.push(x)
else {
if (matched.length > 1)
result.push(matched.join(' '))
matched = []
}
})
console.log(result)
Result: ['dog and cat', 'the dog', 'the cat']
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/494155.html
標籤:javascript 数组 细绳
下一篇:如何判斷哈希的鍵是符號還是字串?
