2017-02-08 12 views
0

検索サブストリングに応じて、<スパン>タグで指定されたストリングの一部をラップする機能を持っています。<span>タグ付きのサブストリングをラップする(ネストあり)

例えば:

は「次に最初の流れ星の夜が来ました。」

それが返されます(と、それは大丈夫だが):

は "次に</span>の< span>の最初の</span>の流れ星の夜< span>に来ました" と。

"最初の"検索文字列。我々は、検索文字列をしようとすると、「RSの最初の」、今それが与える(「RS」が既にGoogleの検索文字列に存在している「FiのRSトン」に含まれていることに注意):

を」その後</span>の<スパン> Fiの<スパン> RS </span>をトン</span>の流れ星」の夜<スパン>を来ました。

しかし、私たちが見てみたいことは最初の結果である:

"</span>を< span>の最初の</span>の流れ星の後に来た夜<スパン>"。

const markSubstring = (string, searchString) => { 
 

 
    _.forEach(searchString.split(' '), function(value){ 
 
     if(value != '') { 
 
      let regEx = new RegExp('(' + value + ')', "ig"); 
 
      string = string.replace(regEx, '<span>$1</span>'); 
 
     } 
 
    }); 
 

 
    return _.map(string.split(/(<span>.*?<\/span>)/), (item, key) => { 
 
     let val = item.split(/<span>(.*?)<\/span>/); 
 
     if (val.length == 3) { return `<span>${val[1]}</span>` } 
 
     return `${val}`; 
 
    }); 
 
}; 
 

 
console.log(markSubstring('Then came the night of the first falling star.', 'first of')); 
 
console.log('---------'); 
 
console.log(markSubstring('Then came the night of the first falling star.', 'first of rs'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

期待される結果を得るために機能を変更するための最良の方法は何ですか?

与えられた文字列

UPDATE:は、その後最初に流れ星の夜が来ました。

いくつかの検索クエリとその期待される結果:

が来た - >そして、最初の立ち下がり星の夜(来ました)。

が最初に来た - >(最初の)落ちる星の夜。

ig first - >次に、(最初の)落下星のn(ig)htを計算します。

最初のrs - >その後、(最初の)落ちる星の夜が来た。

最初のrs am - >次にc(am)e(最初の)落ちる星の夜。

など

だから我々は、スペースで検索文字列を分割し、与えられた文字列でこれらの「サブ検索クエリ」のそれぞれを探してみてください。

new RegExp('(' + value + ')', "ig");の場合、検索がネストされている場合(スタイルだけでなく)、文字列にテキストとして表示されます。<だから、最良の選択肢は、単語(またはその部分が既に強調表示されている)を置いてはいけないと思います。

答えて

2

編集

はOK、私はそれを完璧に、次のロジックを追加しました。

  1. 最も長い単語が最初に検索されるようにすべての検索ワードを長さで並べ替えます。この方法では、短い単語が検索されても長い単語の一部(すでに<span>で囲まれている)に含まれている場合、別のスパンを挿入しないことがわかります。
  2. 私たちは、文字列から各単語を分割し、それがすでに<span>

でラップされていないあなたは、他のそれぞれの単語がいっぱいの単語であることを確認していない部分を作ることによってそれを修正することができることを確認しますワード。

は、例えば、私たちは、正規表現パターンを使用する場合:/(^|\s)(first)(\s|$)/gi たちは言葉firstが始まるか、文字列の最後、スペースが続かなければならないことを確認してください。したがって、この場合、単語rsは単語と見なすことはできません。

アクションでそれを参照してください。

const markSubstring = (string, searchString) => { 
 
    var searchStrings = searchString.split(' ').sort(function(a, b){return b.length - a.length;}); 
 
    
 
    _.forEach(searchStrings, function(value){ 
 
     if(value != '') { 
 
      let regEx = new RegExp('(' + value + ')', "ig"); 
 
      let validationRegEx = new RegExp('<span>.*?(' + value + ').*?<\/span>', "ig"); 
 
      var words = []; 
 
      _.forEach(string.split(' '), function(word) { 
 
       if (!word.match(validationRegEx)) { 
 
       word = word.replace(regEx, '<span>$1</span>'); 
 
       } 
 
       words.push(word); 
 
      })   
 
      string = words.join(' '); 
 
     } 
 
    }); 
 

 
    return _.map(string.split(/(<span>.*?<\/span>)/), (item, key) => { 
 
     let val = item.split(/<span>(.*?)<\/span>/); 
 
     if (val.length == 3) { return `<span>${val[1]}</span>` } 
 
     return `${val}`; 
 
    }); 
 
}; 
 

 
console.log(markSubstring('Then came the night of the first falling star.', 'first of')); 
 
console.log('---------'); 
 
console.log(markSubstring('Then came the night of the first falling star.', 'first of rs')); 
 
console.log('---------'); 
 
console.log(markSubstring('Then came the night of the first falling star. rs is also a word.', 'first of rs'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

+0

は基本的に同じ解決策を考え出したが、私は、私は完全に二重のバックスラッシュのことについて迅速な返信用 – Benjamin

+0

感謝を忘れてしまった気づいたまでそれが仕事をdidntの! [OK]を、ネストの問題を解決しますが、今すぐ完全な単語(末尾にスペース、カンマまたはドット)でのみ動作します。私は正規表現が良くない。 "bla bla first bla bla"や "first rs"(正しい方法)で同じ文字列の "rs"を見つけることができるように、これら2種類の動作をどのように組み合わせることができますか? – Max

+0

その単語がまだスパンでラップされていない場合、文字列の一部をハイライトしたいのですか? –

関連する問題