[英]RegEx via Javascript
我不知道如何用 Javascript 解決這個編碼難題。我從來沒有使用過正則表達式,但我覺得它們是解決它的最佳方法。
比方說,我有這段代碼:
let str = "abcdefabc";
let pattern = "abc";
我需要的是編寫算法,返回 arrays(二維)索引數組,如下所示:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
其中索引是pattern
字母在str
中的位置。 例如,對於str = 'abcdefabc'
和模式pattern = 'abc'
算法必須返回這樣的 arrays:
[0, 1, 2]
(str 中與pattern
匹配的第一個'abc'
:“ abc defabc”);[6, 7, 8]
(str 中與pattern
匹配的最后一個'abc'
:“abcdef abc ”); 這些是顯而易見的例子,但它也必須返回那些:[0, 1, 8]
因為“ ab cdefab c ”[0, 7, 8]
因為“ a bcdefa bc ” 我希望你明白邏輯。 pattern
的順序很重要: str = 'fox1423423man_united_x'
with pattern ='fox'
must return [[0, 1, 2], [0, 1, 21]]
;
str = 'google
with pattern ='fox'
必須返回null
因為兩者之間沒有'fox';
str = 'xof'
with pattern ='fox'
必須返回null
因為字母 go 的方式很重要;
所有字符串都將小寫
我認為這是一個相當干凈的實現,它基於一個簡單的 function,它找到一個字符串中一個字符的所有索引(或者實際上,更一般地說,一個值的所有索引在一個可迭代對象中)。
const allIndices = (xs, t, s = 0) => [...xs].slice (s).flatMap ((x, i) => x == t? [i]: []) const allMatches = (word, sub, i = 0) => sub.length == 0? [[]]: allIndices (word, sub [0], i).flatMap (j => allMatches (word, sub.slice (1), i + j + 1).map (s => [i + j, ...s])) console.log (allMatches ("abcdefabc", "abc")) console.log (allMatches ("fox1423423man_united_x", "fox"))
.as-console-wrapper {max-height: 100%;important: top: 0}
allIndices
使用flatMap
作為一種返回索引而不是值的過濾器。
allMatches
用搜索字符串的第一個字符調用allIndices
,然后在單詞的其余部分和搜索字符串的另一個字符上重復出現,將當前索引與這些結果結合起來。 當搜索字符串為空並返回僅包含一個空數組的結果時,它會觸底。
我們可以編寫一個索引修改較少的版本,但它需要更頻繁地對主字符串進行切片和切塊。
這是一個通過遞歸解決它的解決方案。
它使用indexOf方法來查找字符的位置。
function findTokenPositions(str, tokens) { let arr = []; function recurse (strpos=0, tok=0, accum=[]) { if (tok >= tokens.length) { arr.push(accum); return; } strpos = str.indexOf(tokens[tok], strpos); if (strpos < 0) { return; } accum[tok] = strpos; recurse(strpos+1, tok+1, [...accum]) recurse(strpos+1, tok, [...accum]); } recurse(); return arr; } let tests = [ ["abcdefabc", "abc"], ["fox1423423man_united_x", "fox"], ["hound", "fox"], ["xof", "fox"] ]; tests.forEach(x => { console.log(x[0]+': '+x[1]+' --> ' + JSON.stringify(findTokenPositions(x[0], x[1]))) });
這是另一個使用正則表達式獲取位置的 function。
這只掃描字符串一次。
function getTokenPositions(str, tokens) { let positions = []; let base = []; let m; let re = new RegExp('['+tokens+']','gi'); while (m = re.exec(str)) { positions.push([m[0], m.index]) if(m[0] === tokens[0]) { base.push([m.index]); } } for (let tok=1; tok < tokens.length; tok++) { let arr = []; for (let i=0; i < positions.length; i++) { if (positions[i][0] === tokens[tok]) { let tmp = [...base]; for (let j=0; j < tmp.length; j++) { tmp[j][tok] = positions[i][1]; } tmp.forEach(a=>arr.push([...a])); } } base = [...arr]; } // only return the sorted return base.filter(x => x.every((v,i)=>(i===0||v>=x[i-1]))); } let tests = [ ["abcdefabc", "abc"], ["fox1423423man_united_x", "fox"], ["hound", "fox"], ["xof", "fox"] ]; tests.forEach(x => { console.log(x[0]+': '+x[1]+' --> ' + JSON.stringify(getTokenPositions(x[0], x[1]))) });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.