Good Day
Explanation of what I’m trying to do:
I have a component with checkboxes and names:
[x] foo[ ] bar
[ ] orange
If I select foo, I only want to match records that contain "foo" not "foo (bar)" or any other arrangement. The RegEx I built to do this is:
(?<=(s|^))(${dropdownList.join(‘|’)})(?=(s|$))im
The dropdownList.join will only contain the checked items, so using the list above you’ll get:
(?<=(s|^))(foo)(?=(s|$))im
Now, I’m using this to iterate over a table and look at a value, then disable the row if it doesn’t match. In the table I can have values of foo or foo (bar), what I can’t figure out is why foo (bar) is matching when I run a search for foo.
0 is the return value of "foo".search(regex), which should be -1, if I don’t have "foo", so "foo (bar)" should be -1.
I tested this in https://regex101.com/, and it seems to work, fine when I do it there.
String Value
foo
Search Term
/(?<=(s|^))(foo)(?=(s|$))/im
0
String Value
foo (bar)
Search Term
/(?<=(s|^))(foo)(?=(s|$))/im
0 (Shouldn’t this be -1)
Does anyone know what I did wrong?
Here is the function I’m using for the search, I’ve added updated Regex:
public _validateValues(): Promise < any > {
return new Promise((r) => {
const dropdownList = [];
_.forEach(this.columnSearchHistory, (searchItem: TableSearchHistory) => {
if (searchItem.type === 'dropdown') {
dropdownList.push(this.escapeRegExp(searchItem.value?.toString().trim() ?? ''));
}
});
let searchTerm;
if (dropdownList.length) {
searchTerm = new RegExp(`(^)(${dropdownList.join('|')})($)`, 'im');
}
_.forEach(this.headerList, (row) => {
row.filtered = false;
})
this.activateAllRows();
_.forEach(this.columnSearchHistory, (searchItem: TableSearchHistory) => {
this.headerList[searchItem.headerIndex].filtered = true;
if (searchItem.value && searchItem.type !== 'dropdown') {
searchTerm = new RegExp(this.escapeRegExp(searchItem.value ? .toString().trim()), 'i');
} else if (searchItem.type === 'dropdown') {
searchTerm = new RegExp(`(^)(${dropdownList.join('|')})($)`, 'im');
console.log('Search Term');
console.log(searchTerm);
}
if (searchItem.type === 'number') {
if (searchItem.min === null) {
searchItem.min = Number.NEGATIVE_INFINITY;
}
if (searchItem.max === null) {
searchItem.max = Number.POSITIVE_INFINITY;
}
}
if (searchItem.type === 'date') {
if (searchItem.min === null) {
searchItem.min = new Date('1926');
}
if (searchItem.max === null) {
searchItem.max = new Date(Date.now());
}
}
_.forEach(this.data, (row, rowIdx) => {
let value = row[this.headerList[searchItem.index].key];
if (searchItem.type === 'number') {
if (!value && value !== 0) {
row.active = false;
}
if (!value && value !== 0) {
value = 0;
}
const numericValue = Number(value.toString().replace(/[^d.-]/g, ''));
const max = Number(searchItem.max);
const min = Number(searchItem.min);
if (numericValue < min || numericValue > max) {
row.active = false;
}
} else if (searchItem.type === 'date') {
if (!value) {
row.active = false;
}
if (!value) {
value = new Date();
} else {
value = new Date(value);
}
const max = new Date(searchItem.max);
const min = new Date(searchItem.min);
if (value < min || value > max) {
row.active = false;
}
} else {
const stringValue = value ? value : '';
if (stringValue.toString().trim().search(searchTerm) === -1) {
row.active = false;
}
}
})
})
this.range = {
low: null,
high: null,
search: ''
};
r(this.data);
})
}
Thanks
2
Answers
I think I can help here.
First, your RegExp is not correct in its current form. The ${ code } section will be interpreted literally. You need to declare your Regex as:
I’ve removed the m flag. This is for a multiline string which I don’t believe we have here.
Second, if you try and match the string ‘foo’ it will match any string containing it.
All these will match as they contain the string ‘foo’.
You may want to do a whole string match so try this:
This is simply:
Ok this is what I was thinking:
example:
https://jsfiddle.net/aq8o25nr/2
How does it work? It creates options based on "words". I create a hashmap of all the words. ie:
Map {
‘foo’: 0,
‘bar’: 0,
‘orange’: 0
}
each time you click an option it changes 0 to 1. (identifying the words you want whereas 0 identfies the words you dont want).
That way we just regex the senteces first for the words you want (1s) then we regex that result with words you dont want (the 0s). Thus giving you the matches of checked but omitting the unchecked options. I made it dynamically so you can change the array size of words or change sentences.