I use this function below to quickly find an item in a table
My problem is that this function only searches for text that contains the search string in the given table
I have been trying my best to modify it to match only the text that begins with the search string but not working.
function searchTable(inputVal)
{
var table = $('#supplier_table_body');
table.find('tr').each(function(index, row)
{
var allCells = $(row).find('td');
if(allCells.length > 0)
{
var found = false;
allCells.each(function(index, td)
{
var regExp = new RegExp(inputVal, '^i');
if(regExp.test($(td).text()))
{
found = true;
return false;
}
});
if(found == true)$(row).show();else $(row).hide();
}
});
}
Here is my jquery
$('#itemname').keyup(function()
{
searchTable($(this).val());
});
The string start anchor is not a regex modifier flag, but needs to be part of the expression:
var regExp = new RegExp('^'+inputVal, 'i');
I think you should use \b: new RegExp("\\b" + inputVal, "i"). It finds a match that begins with inputVal.
Not sure if it works, but you may try to add a caret ( ^ ) before the inputVal, while creating the RegExp.
This should only allow words starting with inputVal.
Cheers,
EDIT:
Like so :
new RegExp("^" + inputVal, "i")
This answer posted as a community wiki answer because I think it solves the problem you're having and simplifies your code (but is too long to post as a comment), so I'd suggest, though currently untested, amending your function to:
function searchTable(needle){
var table = $('#supplier_table_body'),
cells = table.find('td');
cells.filter(function(){
return this.textContent.indexOf(needle) !== 0;
}).closest('tr').hide();
}
Simple proof of concept.
Related
I'm trying to manipulate a string that has tested as a positive match against my regex statement.
My regex statement is /\[table=\d](.*?)\[\/table] / gmi and an example of a positive match would be [table=1]Cell 1[c]Cell 2[/table]. I'm searching for matches within a certain div, which I'll call .foo in the code below.
However, once the search comes back saying it has found a match, I want to have the section that was identified as a match returned back to me so that I can start manipulating a specific section of it, namely count the number of times [c] appears and reference the number in [table=1].
(function(regexCheck) {
var regex = /\[table=\d](.*?)\[\/table] / gmi;
$('.foo').each(function() {
var html = $(this).html();
var change = false;
while (regex[0].test(html)) {
change = true;
//Somehow return string?
}
});
})(jQuery);
I'm quite new to javascript and especially new to RegEx, so I apologise if this code is crude.
Thanks for all of your help in advance.
Use exec instead of test and keep the resulting match object:
var match;
while ((match = regex[0].exec(html)) != null) {
change = true;
// use `match[0]` for the full match, or `match[1]` and onward for capture groups
}
Simple example (since your snippet isn't runnable, I've just created a simple one instead):
var str = "test 1 test 2 test 3";
var regex = /test (\d)/g;
var match;
while ((match = regex.exec(str)) !== null) {
console.log("match = " + JSON.stringify(match));
}
currently I am very confused! I have been trying to solve this for a while, and can't seem to crack it. I can't even find an answer on Google.
Currently I am using this Regex I wrote in Javascript:
((?: {4,}|\t+)(?:.*))
Simply, it matches everything that is 4+ spaces out or 1+ tabs out in a textarea. Yea, that sounds familiar you say? It is simply what Stack Overflow does for codeblocks. Now, I have run in to an issue.
Basically I am wanting to replace all of these instances found in the textarea, but first I want to back them up to an array. Now, I am not sure how I grab each match found, and insert it in to the array.
Here is what I have so far:
.replace(/((?: {4,}|\t+)(?:.*))/gi, function (m, g1, g2) {
return //STUCK HERE
}); //Matches Bold
So simply, I just want to grab all matches found in a textarea (Either indented or 4 spaces) and then I would like to add the contents of the match to an array.
How would I go about doing this? Please Help!
You can hit two targets with one bullet:
var items = [];
var re = /((?: {4,}|\t+)(?:.*))/g;
textarea.value = textarea.value.replace(re, function ($0, $1) {
items.push($1);
return 'replacement';
});
If you want to get the code blocks back then:
var codeLines = [];
var reMarkers = /\{\{(.*?)\}\}/g;
var reCodeBlocks = /((?: {4,}|\t+)(?:.*))/g;
var text = textarea.value;
// save and remove code blocks
text = text.replace(reCodeBlocks, function ($0, $1) {
var marker = '{{' + codeLines.length + '}}';
codeLines.push($1);
return marker;
});
// revert to previous state
text = text.replace(reMarkers, function ($0, $1) {
return codeLines[parseInt($1, 10)];
});
If you want to get the array of matches, you can use match() function :
var matchesArray = $('textarea').val().match('/((?: {4,}|\t+)(?:.*))/gi');
and if you want to replace, use simple replace() function :
$('textarea').val().replace('/((?: {4,}|\t+)(?:.*))/gi', 'replaceWith');
Hope this helps.
I need to search for a word in text. For this I used this regex:
var re =/duration='\d+'/ig;
var i = text.match(re);
This gives me an array of matches like "duration='300'", "duration='400'",...
I need to get only numbers. without duration=''
You can use a capturing group:
var re = /duration='(\d+)'/ig;
var match = re.exec(text);
while (match != null) {
// matched text: match[1]
match = re.exec(text);
}
Tim's answer works well (and I'm not sure why the OP says it is not what he/she wants). That said, here is another way to do it using the String.replace() method with a callback function replacement value:
function getDurations(text) {
var re =/duration='(\d+)'/ig;
var i = [];
text.replace(re, function(m0, m1){i.push(m1); return '';});
return i;
}
Note that this technique requires no loop and is quite efficient getting the job done in a single statement.
I am checking a collection and replacing all
<Localisation container="test">To translate</Localisation>
tags with text.
The next codes does what I want:
var localisationRegex = new RegExp("(?:<|<)(?:LocalisationKey|locale).+?(?:container|cont)=[\\\\]?(?:['\"]|("))(.+?)[\\\\]?(?:['\"]|(")).*?(?:>|>)(.*?)(?:<|<)/(?:LocalisationKey|locale)(?:>|>)", "ig");
match = localisationRegex.exec(parsedData);
while (match != null) {
var localeLength = match[0].length;
var value = match[4];
parsedData = parsedData.substr(0, match.index) + this.GetLocaleValue(value) + parsedData.substr(match.index + localeLength);
match = localisationRegex.exec(parsedData);
}
But, when the the string I replace with, Is longer then the original string, the index/place where it will start to search for the next match, is wrong (to far). This sometimes leads to tags not found.
Setting aside the (important) question as to whether the approach is a good one, if it were me I'd avoid the problem of indexing through the source text by using a function argument to the regex:
var localizer = this;
var result = parsedData.replace(localisationRegex, function(_, value) {
return localizer.GetLocaleValue(value);
});
That will replace the tags with the localized content.
I have a string (partly HTML) where I want to replace the string :-) into bbcode :wink:. But this replacement should not happen within <pre>, but in any other tag (or even not within a tag).
For example, I want to replace
:-)<pre>:-)</pre><blockquote>:-)</blockquote>
to:
:wink:<pre>:-)</pre><blockquote>:wink:</blockquote>
I already tried it with the following RegEx, but it does not work (nothing gets replaced):
var s = ':-)<pre>:-)</pre><blockquote>:-)</blockquote>';
var regex = /:\-\)(?!(^<pre>).*<\/pre>)/g;
var r = s.replace(regex, ':wink:');
Can someone please help me? :-)
This ought to do it:-
var src = ":-)<pre>:-)</pre><blockquote>:-)</blockquote>"
var result = src.replace(/(<pre>(?:[^<](?!\/pre))*<\/pre>)|(\:\-\))/gi, fnCallback)
function fnCallback(s)
{
if (s == ":-)") return ":wink:"
return s;
}
alert(result);
It works because any pre element will get picked up by the first option in the regex and once consumed means that any contained :-) can't be matched since the processor will have moved beyond it.
You could avoid hellish regexes altogether if you use a suitable library such as jQuery, e.g.:
var excludeThese = ['pre'];
// loop over all elements on page, replacing :-) with :wink: for anything
// that is *not* a tag name in the excludeThese array
$('* not:(' + excludeThese.join(',') + ')').each(function() {
$(this).html($(this).html().replace(/:\-\)/,':wink:'));
});
Just thought it'd be worth offering a DOM solution:
E.g.
var div = document.createElement('div');
div.innerHTML = ":-)<pre>:-)</pre><blockquote>:-)</blockquote>";
replace(div, /:-\)/g, ":wink:", function(){
// Custom filter function.
// Returns false for <pre> elements.
return this.nodeName.toLowerCase() !== 'pre';
});
div.innerHTML; // <== here's your new string!
And here's the replace function:
function replace(element, regex, replacement, filter) {
var cur = element.firstChild;
if (cur) do {
if ( !filter || filter.call(cur) ) {
if ( cur.nodeType == 1 ) {
replace( cur, regex, replacement );
} else {
cur.data = cur.data.replace( regex, replacement );
}
}
} while ( cur = cur.nextSibling );
}
Almost good: Your negative lookbehind and lookahead where not in the right position and need a slight adjustment:
/(?<!(<pre>)):-\)(?!(<\/pre>))/g
Looks for all ":-)"
...but not if there is a <pre> behind (the regex cursor is!)
...but not if there is a </pre> before (the regex cursor is!)
as a side effect though: <pre>:-):-)</pre> works too but not <pre>:-):-):-)</pre>
https://regex101.com/r/CO0DAD/1
ps. this is a firefox 104 browser (could be different in others)
try with
var regex = /:-)(?!(^)*</pre>)/g;