Ruven JR. Maerson
Ruven JR. Maerson

Reputation: 309

return a searched string + previous and next word

I have a string like this: This is my text

When i search for a string like is i would like to get This is my as result, when i search for This i would like to get This is and for text the result should be my text

So i always try to find a string and get the searched string + the previous and next word if exists.

I know i can search with mystring.match('search') for a string, giving me the index but how i go further, maybe using split?

Maybe someone of you have an idea.

Thx for any help

ruven

Upvotes: 2

Views: 3206

Answers (5)

Julius
Julius

Reputation: 2483

Yet another solution:

var input = 'Text? This is my simple text string where I use word TEXT a few times. Is it finding my text?'
var text = 'text';

input = input.toString();
text = text.toString().replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');

var preLength = 7;

var search = function () {
    if (position !== -1) {
        var sliceStart = (position - preLength) >= 0 ? position - preLength : 0;
        var sliceEnd = position + text.length + preLength;

        var matchedText = input.slice(sliceStart, sliceEnd).trim();

        var preText = ((position - preLength) >= 0) && !result.length ? '...' : '';
        var postText = input.slice(sliceEnd).trim().length > 0 ? '...' : '';

        result = result + preText + matchedText + postText;

        input = input.slice(sliceEnd);
        lowercaseInput = lowercaseInput.slice(sliceEnd);

        position = lowercaseInput.search(lowercaseText);
    }
}

var lowercaseInput = input.toLowerCase();
var lowercaseText = text.toLowerCase();

var result = '';
var position = lowercaseInput.search(lowercaseText);

while (position !== -1) {
    search();
}

console.log(result);

This looks up for a searched text and returns a result with all matches.

http://jsfiddle.net/bqwn1whq/

Upvotes: 1

David Thomas
David Thomas

Reputation: 253318

I'd suggest the following approach, which uses a functional approach that allows you to pass both the word you're searching for and a string in which to search for that word:

function findWordAndNeighbours(needle, haystack) {
    if (!needle || !haystack) {
        return false;
    }
    else {
        var re = new RegExp('(\\S+[\\b\\s]' + needle + '[\\b\\s]\\S+)', 'i'),
            foundWords = haystack.match(re)[0].split(/\s+/),
            foundFragment = foundWords.join(' ');
        return foundFragment;
    }
}

var sentenceFragment = findWordAndNeighbours('test', 'This is a Test of a matching thing.');

console.log(sentenceFragment);

JS Fiddle demo.

Edited to update the above to include some error-catching, basically checking that there are some regex matches before trying to work with those matches:

function findWordAndNeighbours(needle, haystack) {
    if (!needle || !haystack) {
        return false;
    }
    else {
        var re = new RegExp('(\\S+[\\b\\s]' + needle + '[\\b\\s]\\S+)', 'i'),
            matches = haystack.match(re);
        if (matches) {
            // this is for if you wanted the individual words (as an array)
            var foundWords = haystack.match(re)[0].split(/\s+/),
                // this is to return the found sentence-fragment:
                foundFragment = foundWords.join(' ');
            return foundFragment;
        }
        else {
            /* this just follows the indexOf() pattern of, if you'd rather
               'return false' instead, that's entirely your call. */
            return -1;
        }
    }
}

var sentenceFragment = findWordAndNeighbours('test', 'This is a Test of a matching thing.');

console.log(sentenceFragment);

JS Fiddle demo.

Edited to correct for problems identified by OP in the comments (below):

but this will not work if you search for This or thing, so the first or last word

The use of the ? operands/special characters (meaning match the preceding character/group zero, or one, times) seems to correct for the problems in searching for the first, and last, word in the supplied string.

function findWordAndNeighbours(needle, haystack) {
    if (!needle || !haystack) {
        return false;
    }
    else {
        var re = new RegExp('((\\S+[\\b\\s]?)' + needle + '([\\b\\s]?\\S+))', 'i'),
            matches = haystack.match(re);
        console.log(matches);
        if (matches) {
            var foundWords = haystack.match(re)[0].split(/\s+/),
                foundFragment = foundWords.join(' ');
            return foundFragment;
        }
        else {
            return -1;
        }
    }
}

var sentenceFragment = findWordAndNeighbours('es', 'This is a Test of a matching thing.');

console.log(sentenceFragment);

However I was unable to find a neat way of searching for a substring from a given word, for example the es (from test, as in the example). The function returns the complete word (in this case test). If you want a naive correction for that behaviour, then I you could easily add in an if (needle == matches[0]) {/* do something */} check, and alter the behaviour as you think best. But I'm not entirely sure what the best way to handle that would be.

References:

Upvotes: 3

Emre Karataşoğlu
Emre Karataşoğlu

Reputation: 1719

in my opinion For "this i" etc you can use regex , 3 or 4 case for start with ^this ? but this search is unhealty if not be careful. space and unmatching terms can create problem hard to match this i*. for substring match match(/yoursearchterm/[A-Za-z0-9_-]*/i) if not match then you use substring of yoursearchterm like yoursearchterm.substring(0,yoursearchterm.length-1) in for loop try to make -1 to -i for similarity ,

Full Text search or like expression in sql . For better result the Regex for sql may help you but both of them {like and regex not very fast} .for matching by similarity like apple is your data and the appla or app or appl or eppl is your search them you can make them find via the levenstein . in php http://php.net/manual/en/function.levenshtein.php for a substring or long sentenced you can use the way that split {or explode } the data by space . ie here I am and your data splitted 3 here I am both of them you can apply the lev or like regex matching is successfull but you have to think of performance your query

Upvotes: 0

Silagy
Silagy

Reputation: 3083

Try this

Here is working example

The code is in javascript

var str = "This is my text";

var strArr = str.split(" ");

var seacrhWord = "is";

for (i=0; i<strArr.length; i++)
   {
      if ( strArr[i] == seacrhWord)
      {
          var result = "";
          if (strArr[i-1] != null)
             result += strArr[i-1]

          result += " " + strArr[i];

          if (strArr[i+1] != null)
             result += " " + strArr[i+1];

          alert(result);
      }
  }

Upvotes: 1

Danil Speransky
Danil Speransky

Reputation: 30453

'asd d This is my text a'.match(/\s(\w*\sis\s\w*)\s/)[1] //=> "This is my"

Upvotes: 1

Related Questions