Reputation: 309
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
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.
Upvotes: 1
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);
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);
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
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
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
Reputation: 30453
'asd d This is my text a'.match(/\s(\w*\sis\s\w*)\s/)[1] //=> "This is my"
Upvotes: 1