I need to use regexp for matching and the code below works fine. However, I need to KEEP the dollar sign ($) as a true dollar sign and not a special character.
I've tried excluding but nothing is working.
IE: [^$]
Here's the code. It works as expected except when the text contains a $ or IS the $.
textNode = "$19,000";
regex = RegExp("$19,000",'ig');
text = '$';
textReplacerFunc: function (textNode, regex, text) {
var sTag = '<span class="highlight">';
var eTag = '</span>';
var re = '(?![^<>]*>)(' + text + '(?!#8212;))';
var regExp = new RegExp(re, 'ig');
textNode.data = textNode.data.replace(regExp, sTag + '$1' + eTag);
},
RESULT: $ not highlighted. desired results:
$19,000
Make sure to double escape the $ as in :
text = '\\$';
Since you are using construction of RegExp instance using a string here.
Related
I want to add a (variable) tag to values with regex, the pattern works fine with PHP but I have troubles implementing it into JavaScript.
The pattern is (value is the variable):
/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is
I escaped the backslashes:
var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "" + value + ""));
But this seem not to be right, I logged the pattern and its exactly what it should be.
Any ideas?
To create the regex from a string, you have to use JavaScript's RegExp object.
If you also want to match/replace more than one time, then you must add the g (global match) flag. Here's an example:
var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
In the general case, escape the string before using as regex:
Not every string is a valid regex, though: there are some speciall characters, like ( or [. To work around this issue, simply escape the string before turning it into a regex. A utility function for that goes in the sample below:
function escapeRegExp(stringToGoIntoTheRegex) {
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;
var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.
JSFiddle demo here.
Note: the regex in the question uses the s modifier, which didn't exist at the time of the question, but does exist -- a s (dotall) flag/modifier in JavaScript -- today.
If you are trying to use a variable value in the expression, you must use the RegExp "constructor".
var regex = "(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
I found I had to double slash the \b to get it working. For example to remove "1x" words from a string using a variable, I needed to use:
str = "1x";
var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
inv=inv.replace(regex, "");
You don't need the " to define a regular expression so just:
var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax
If value is a variable and you want a dynamic regular expression then you can't use this notation; use the alternative notation.
String.replace also accepts strings as input, so you can do "fox".replace("fox", "bear");
Alternative:
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");
Keep in mind that if value contains regular expressions characters like (, [ and ? you will need to escape them.
I found this thread useful - so I thought I would add the answer to my own problem.
I wanted to edit a database configuration file (datastax cassandra) from a node application in javascript and for one of the settings in the file I needed to match on a string and then replace the line following it.
This was my solution.
dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'
// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
// need to use double escape '\\' when putting regex in strings !
var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
var myRegExp = new RegExp(searchString + re, "g");
var match = myRegExp.exec(data);
var replaceThis = match[1];
var writeString = data.replace(replaceThis, newString);
fs.writeFile(file, writeString, 'utf-8', function (err) {
if (err) throw err;
console.log(file + ' updated');
});
});
}
searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"
replaceStringNextLine(dse_cassandra_yaml, searchString, newString );
After running, it will change the existing data directory setting to the new one:
config file before:
data_file_directories:
- /var/lib/cassandra/data
config file after:
data_file_directories:
- /mnt/cassandra/data
Much easier way: use template literals.
var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Using string variable(s) content as part of a more complex composed regex expression (es6|ts)
This example will replace all urls using my-domain.com to my-other-domain (both are variables).
You can do dynamic regexs by combining string values and other regex expressions within a raw string template. Using String.raw will prevent javascript from escaping any character within your string values.
// Strings with some data
const domainStr = 'my-domain.com'
const newDomain = 'my-other-domain.com'
// Make sure your string is regex friendly
// This will replace dots for '\'.
const regexUrl = /\./gm;
const substr = `\\\.`;
const domain = domainStr.replace(regexUrl, substr);
// domain is a regex friendly string: 'my-domain\.com'
console.log('Regex expresion for domain', domain)
// HERE!!! You can 'assemble a complex regex using string pieces.
const re = new RegExp( String.raw `([\'|\"]https:\/\/)(${domain})(\S+[\'|\"])`, 'gm');
// now I'll use the regex expression groups to replace the domain
const domainSubst = `$1${newDomain}$3`;
// const page contains all the html text
const result = page.replace(re, domainSubst);
note: Don't forget to use regex101.com to create, test and export REGEX code.
var string = "Hi welcome to stack overflow"
var toSearch = "stack"
//case insensitive search
var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'
https://jsfiddle.net/9f0mb6Lz/
Hope this helps
I need a little help with regex extraction. The body content of the email appears like this when retrieved in google sheet from gmail (has asterisk before and after name /phone / email which is hyperlinked)
Body Content after being retrived from Gmail
Email: *abc#gmail.com `<abc#gmail.com>`*
First Name: *John Doe*
Phone Number: *123456789*
My current Regex code retrieves the data like this
*abc#gmail.com `<abc#gmail.com>`*
*John Doe*
*123456789*
What changes should be made to the code so that it ignores the asterisk before and after for all these and the email is retrieved as abc#gmail.com ignoring the second part of the hyperlink format? Like
abc#gmail.com
John Doe
123456789
My Code is
function extractDetails(message){
var emailData = {
date: "Null",
fullName: "Null",
emailAddr: "Null",
phoneNum: "Null",
}
var emailKeywords = {
fullName: "First Name:",
emailAddr: "Email:",
phoneNum: "Phone Number:",
}
emailData.date = message.getDate();
emailData.body = message.getPlainBody();
var regExp;
regExp = new RegExp("(?<=" + emailKeywords.fullName + ").*");
emailData.fullName = emailData.body.match(regExp).toString().trim();
regExp = new RegExp("(?<=" + emailKeywords.phoneNum + ").*");
emailData.phoneNum = emailData.body.match(regExp).toString().trim();
regExp = new RegExp("(?<=" + emailKeywords.emailAddr + ").*");
emailData.emailAddr = emailData.body.match(regExp).toString().trim();
Replace the last 6 lines of your code with:
regExp = new RegExp("(?<=" + emailKeywords.fullName + "\\s*\\*).*?(?=\\*)");
emailData.fullName = emailData.body.match(regExp).toString();
regExp = new RegExp("(?<=" + emailKeywords.phoneNum + "\\s*\\*).*?(?=\\*)");
emailData.phoneNum = emailData.body.match(regExp).toString();
regExp = new RegExp("(?<=" + emailKeywords.emailAddr + "\\s*\\*).*?(?=\\s)");
emailData.emailAddr = emailData.body.match(regExp).toString();
(?<=Email:\s*\*).*?(?=\s)
(?<=Email:\s*\*) go to the point where it preceded by Email: followed by zero or more whitespace character \s*, followed by a literal *.
.*? then match any character except for new lines as few times as possible. Until a whitespace character appears (?=\s), See regex demo.
(?<=First Name:\s*\*).*?(?=\*)
(?<=First Name:\s*\*) go to the point where it preceded by First Name: followed by zero or more whitespace character \s*, followed by a literal *
.*? then match any character except for new lines as few times as possible. Until a literal * character appears (?=\*), See regex demo.
Using notepad++, how can I replace the -s noted by the carats? The dashes I want to replace occurs every 7th character in the string.
11.871-2-2.737-2.00334-2
^ ^ ^
123456781234567812345678
It's pretty simple since it's only dashes:
(\S*?)-
Begin capture group.............................. (
Find any number of non-space chars... \S*
Lazily until...............................................?
End capture group...................................)
No capture find hyphen...........................-
Demo 1
var str = `11.871-2-2.737-2.00334-2`;
var sub = `$1`;
var rgx = /(\S*?)-/g;
var res = str.replace(rgx, sub);
console.log(res);
"There is a dash (right above 1) that I would like to preserve. This seems to get rid of all the dashes in the string"
The question clearly shows that there isn't a dash at the "1 position", but since there's a possibility that it's possible considering the pattern (n7). Don't have time to break it down, but I can refer you to a proper definition of the meta char \b.
Demo 2
var str = `-11.871-2-2.737-2.00334-2`;
var sub = `$1$2`;
var rgx = /\b[-]{1}(\S*?)-(\S*?)\b/g;
var res = str.replace(rgx, sub);
console.log(res);
Search for ([0-9\.-]{6,6})-
Replace with: $1MY_SEPARATOR
If I am doing this it is working fine:
val string = "somestring;userid=someidT;otherstuffs"
var pattern = """[;?&]userid=([^;&]+)?(;|&|$)""".r
val result = pattern.findFirstMatchIn(string).get;
But I am getting an error when I am doing this
val string = "somestring;userid=someidT;otherstuffs"
val id_name = "userid"
var pattern = """[;?&]""" + id_name + """=([^;&]+)?(;|&|$)""".r
val result = pattern.findFirstMatchIn(string).get;
This is the error:
error: value findFirstMatchIn is not a member of String
You may use an interpolated string literal and use a bit simpler regex:
val string = "somestring;userid=someidT;otherstuffs"
val id_name = "userid"
var pattern = s"[;?&]${id_name}=([^;&]*)".r
val result = pattern.findFirstMatchIn(string).get.group(1)
println(result)
// => someidT
See the Scala demo.
The [;?&]$id_name=([^;&]*) pattern finds ;, ? or & and then userId (since ${id_name} is interpolated) and then = is matched and then any 0+ chars other than ; and & are captured into Group 1 that is returned.
NOTE: if you want to use a $ as an end of string anchor in the interpolated string literal use $$.
Also, remember to Regex.quote("pattern") if the variable may contain special regex operators like (, ), [, etc. See Scala: regex, escape string.
Add parenthesis around the string so that regex is made after the string has been constructed instead of the other way around:
var pattern = ("[;?&]" + id_name + "=([^;&]+)?(;|&|$)").r
// pattern: scala.util.matching.Regex = [;?&]userid=([^;&]+)?(;|&|$)
val result = pattern.findFirstMatchIn(string).get;
// result: scala.util.matching.Regex.Match = ;userid=someidT;
I'm creating a basic text editor and I'm using regex to achieve a find and replace function. To do this I've gotten this code:
Private Function GetRegExpression() As Regex
Dim result As Regex
Dim regExString As [String]
' Get what the user entered
If TabControl1.SelectedIndex = 0 Then
regExString = txtbx_Find2.Text
ElseIf TabControl1.SelectedIndex = 1 Then
regExString = txtbx_Find.Text
End If
If chkMatchCase.Checked Then
result = New Regex(regExString)
Else
result = New Regex(regExString, RegexOptions.IgnoreCase)
End If
Return result
End Function
And this is the Find method
Private Sub FindText()
''
Dim WpfTest1 As New Spellpad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
' Is this the first time find is called?
' Then make instances of RegEx and Match
If isFirstFind Then
regex = GetRegExpression()
match = regex.Match(TheTextBox.Text)
isFirstFind = False
Else
' match.NextMatch() is also ok, except in Replace
' In replace as text is changing, it is necessary to
' find again
'match = match.NextMatch();
match = regex.Match(TheTextBox.Text, match.Index + 1)
End If
' found a match?
If match.Success Then
' then select it
Dim row As Integer = TheTextBox.GetLineIndexFromCharacterIndex(TheTextBox.CaretIndex)
MoveCaretToLine(TheTextBox, row + 1)
TheTextBox.SelectionStart = match.Index
TheTextBox.SelectionLength = match.Length
Else
If TabControl1.SelectedIndex = 0 Then
MessageBox.Show([String].Format("Cannot find ""{0}"" ", txtbx_Find2.Text), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
ElseIf TabControl1.SelectedIndex = 1 Then
MessageBox.Show([String].Format("Cannot find ""{0}"" ", txtbx_Find.Text), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
isFirstFind = True
End If
End Sub
When I run the program I get errors:
For ?, parsing "?" - Quantifier {x,y} following nothing.; and
For *, parsing "*" - Quantifier {x,y} following nothing.
It's as if I can't use these but I really need to. How can I solve this problem?
? and * are quantifiers in regular expressions:
? is used to specify that something is optional, for instance b?au can match both bau and au.
* means the group with which it binds can be repeated zero, one or multiple times: for instance ba*u can bath bu, bau, baau, baaaaaaaau,...
Now most regular expressions use {l,u} as a third pattern with l the lower bound on the number of times something is repeated, and u the upper bound on the number of occurences. So ? is replaced by {0,1} and * by {0,}.
Now if you provide them without any character before them, evidently, the regex parser doesn't know what you mean. In other words if you do (used csharp, but the ideas are generally applicable):
$ csharp
Mono C# Shell, type "help;" for help
Enter statements below.
csharp> Regex r = new Regex("fo*bar");
csharp> r.Replace("Fooobar fooobar fbar fobar","<MATCH>");
"Fooobar <MATCH> <MATCH> <MATCH>"
csharp> r.Replace("fooobar far qux fooobar quux fbar echo fobar","<MATCH>");
"<MATCH> far qux <MATCH> quux <MATCH> echo <MATCH>"
If you wish to do a "raw text find and replace", you should use string.Replace.
EDIT:
Another way to process them is by escaping special regex characters. Ironically enough, you can do this by replacing them by a regex ;).
Private Function GetRegExpression() As Regex
Dim result As Regex
Dim regExString As [String]
' Get what the user entered
If TabControl1.SelectedIndex = 0 Then
regExString = txtbx_Find2.Text
ElseIf TabControl1.SelectedIndex = 1 Then
regExString = txtbx_Find.Text
End If
'Added code
Dim baseRegex As Regex = new Regex("[\\.$^{\[(|)*+?]")
regExString = baseRegex.Replace(regExString,"\$0")
'End added code
If chkMatchCase.Checked Then
result = New Regex(regExString)
Else
result = New Regex(regExString, RegexOptions.IgnoreCase)
End If
Return result
End Function