I'm trying to highlight the username of a user when it's detected in a string like #login. Here's the code which doesn't seem to work:
function parse(string) {
var regex = new RegExp('(\W|^)#('+username+')(\W|$)', 'i');
return String(string).replace(regex, '<span class="label radius">#$2</span>');
}
And here's a jsfiddle to test it: http://jsfiddle.net/2pmLT/3/
When I type my #login, it highlight it but only if it's the only text in the string: "#login haha" won't work.
You need to escape your backslashes. Also, you should also add $1 and $3, else you drop your spaces. Use a g-flag for multiple replaces
http://jsfiddle.net/7h8Aq/
function parse(string) {
var regex = new RegExp('(\\W|^)#('+username+')(\\W|$)', 'ig');
return string.replace(regex, '$1<span class="label radius">#$2</span>$3');
}
Here you go, you only need to replace certain instances, so there's no nee to match the whole string, you also need to specify the global g flag for regex:
function parse(text) {
return text.replace(new RegExp('(#' + username + ')', 'g'),
'<span class="label radius">$1</span>');
}
Consider this example instance.
HTML
<div id="test-block">
<div class='label'></div>
</div>
JQuery
$('#test').on('keyup', function(e) {
$('.label').text(parse($(this).val()));
});
function parse(myString) {
var find = "(\W|^)#(" + username + ")(\W|$)";
var regex = new RegExp(find, 'i');
return myString.replace(regex, '#$2');
}
Related
I have made this script and i have a question:
$(document).ready(function() {
$('html').html(function(i, v) {
var searchMask = "think";
var regEx = new RegExp(searchMask, "ig");
return v.replace(regEx, '<span style="background-color:yellow;">$&</span>');
});
});
<p id="demo">String replace. any Think new replace</p>
This script take a word inside the html like "think" and replace it with a background-color span with the searched word inside.
If you see the fiddle initially "think" had the "T" capital, after the replacement was of course changed to tiny "t". I would like the script to always keep case sensitive, can this be done with js?
I want to be able to change the words by searching them with the tiny ones.
fiddle: http://jsfiddle.net/GHQU6/9/
You could insert the found string with $& into the replacement.
var searchMask = "think",
regEx = new RegExp(searchMask, "ig"),
v = 'THINK, but do not think too much!';
document.body.innerHTML += v.replace(regEx, '<span style="background-color:yellow;">$&</span>');
Because you're replacing with searchMask and searchMask = "think"
Change it to Think. There is an exact word replace is happening.
You can change it to &$ to replace with found word.
return v.replace(regEx, '<span style="background-color:yellow;">$&</span>');
$(document).ready(function() {
$('html').html(function(i, v) {
var searchMask = "think";
var regEx = new RegExp(searchMask, "ig");
return v.replace(regEx, '<span style="background-color:yellow;">$&</span>');
});
});
<p id="demo">String replace. any Think new replace</p>
I've tried to get my head around regex, but I still can't get it.
I want to turn the following String + some variables into a regex:
"[url href=" + objectId + "]" + objectId2 + "[/url]"
I tried the following, since I read somewhere that brackets and slashes need to be escaped:
/\[url href=/ + objectId + /\]/ + objectId2 + /\[\/\url\]/g
But that isn't working.
I want to use it to replace the whole expression into HTML wherever it matches in a String.
You are correct that brackets and backslashes need to be escaped in a regular expression, but you can't create a regex by adding together regex literals like your /\[url href=/ + objectId + /\]/ attempt. To build a regex dynamically like that you have to use string concatenation and pass the result to new RegExp(). So as a starting point for your text you'd need this:
new RegExp("\\[url href=" + objectId + "\\]" + objectId2 + "\\[/url\\]")
Note all of the double-backslashes - that's because backslashes need to be escaped in string literals, so "\\[" creates a string containing a single backslash and then a bracket, which is what you want in your regex.
But if you want to extract the matched href and content for use in creating an anchor then you need capturing parentheses:
new RegExp("\\[url href=(" + objectId + ")\\](" + objectId2 + ")\\[/url\\]")
But that's still not enough for your purposes because objectId and objectId2 could (or will, given the first is a url) contain other characters that need to be escaped in a regex too, e.g., .+?(), etc. So here's a function that can escape all of the necessary characters:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
We can't just call that function on the whole thing, because you need unescaped parentheses for your capturing sub matches, so just call it on the two variables:
var urlRegex = new RegExp("\\[url href=("
+ escapeStringForRegex(objectId)
+ ")\\]("
+ escapeStringForRegex(objectId2)
+ ")\\[/url\\]");
Kind of messy, but seems to do the job as you can see here:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str, objectId, objectId2) {
var urlRegex = new RegExp("\\[url href=(" + escapeStringForRegex(objectId) + ")\\](" + escapeStringForRegex(objectId2) + ")\\[/url\\]", "g");
return str.replace(urlRegex, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
var objectId = document.getElementById("objectId").value;
var objectId2 = document.getElementById("objectId2").value;
document.getElementById("output").value =
createAnchors(str, objectId, objectId2);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">This is just some text that you can edit to try things out. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks.</textarea>
ObjectId:<input id="objectId" value="http://test.com.au?param=1"><br>
ObjectId2:<input id="objectId2" value="Test URL"><br>
<button>Test</button>
<textarea id="output"></textarea>
Note that the above searches only for [url]s in your string that have the particular href and content specified in the objectId and objectId2 variables. If you just want to change all [url]s into anchors regardless of what href and text they contain then use this:
.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>")
Demo:
function escapeStringForRegex(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
function createAnchors(str) {
return str.replace(/\[url href=([^\]]+)\]([^\]]+)\[\/url\]/g, "<a href='$1'>$2</a>");
}
document.querySelector("button").addEventListener("click", function() {
var str = document.getElementById("input").value;
document.getElementById("output").value = createAnchors(str);
});
textarea { width : 100%; height: 80px; }
Input:<br><textarea id="input">Testing. [url href=http://test.com.au?param=1]Test URL[/url]. Thanks. Another URL: [url href=https://something.com/test?param=1¶m2=123]Test URL 2[/url]</textarea>
<button>Test</button>
<textarea id="output"></textarea>
It's like:
var rx = new RegExp('\\[url\\shref='+objectId+'\\]'+objectId2+'\\[\\/url\\]');
new RegExp("[url href=" + objectId + "]" + objectId2 + "[\url]")
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
I am building an autocomplete in JavaScript that needs to highlight words when doing a search:
That works fine, but there's an issue with escaped characters.
When trying to highlight a text with escaped characters (for example regex &>< example), the following is happening:
That's happening because I am doing the following:
element.innerHTML.replace(/a/g, highlight)
function highlight(str) {
return '<span class="foo"' + '>' + str + '</span>';
}
and innerHTML includes the word &, so it makes sense.
In conclusion, I need a way to solve that so I would like a function that:
receives a and regex <br> example and returns regex <br> ex<span class="foo">a</span>mple
receives r and regex <br> example and returns <span class="foo">r</span>egex <b<span class="foo">r</span>> example
receives < and regex <br> example and returns regex <span class="foo"><</span>br> example
The entries may or may not contain html blocks, see the issue here (search for <br> or &)
str.replace only returns a new string with the intended replacements. The original string is unchanged.
var str = 'replace me';
var str2 = str.replace(/e/g, 'E');
// For display only
document.write('<pre>' + JSON.stringify({
str: str,
str2: str2
}, null, 2) + '</pre>');
Therefore the code needs to set the returned value from the replace back to the desired element.
Also, innerHTML will return the escaped text rather than the unescaped text. This could be unescaped itself within the function but why bother if you can use textContent. However by using innerHTML when it's time to set the highlighted text to the element it will auto-escape the text for us. :)
UPDATE: the values are passed to the function and then set to the element:
NOTES:
The regexp could probably be made a bit more robust to avoid having to handle the special case using lastIndex
There needs to be some protection on the input as someone could provide a nasty regexp pattern. There is a minimal protection check in this example.
higlightElemById('a', 'regex &>< example', 'a');
higlightElemById('b', 'regex &>< example', '&');
higlightElemById('c', 'regex <br> example', '<');
higlightElemById('d', 'regex <br> example', 'e');
higlightElemById('e', 'regex <br> example', '[aex]');
function higlightElemById(id, str, match) {
var itemElem = document.getElementById(id);
// minimal regexp escape to prevent shenanigans
var safeMatch = match.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// construct regexp to match highlight text
var regexp = new RegExp('(.*?)(' + safeMatch + ')', 'g');
var text = '';
var lastIndex;
var matches;
while (matches = regexp.exec(str)) {
// Escape the non-matching prefix
text += escapeHTML(matches[1]);
// Highlight the match
text += highlight(matches[2]);
// Cache the lastIndex in case no regexp at end
lastIndex = regexp.lastIndex;
}
if (text) {
text += escapeHTML(str.substr(lastIndex));
} else {
text += escapeHTML(str);
}
itemElem.innerHTML = text;
}
function highlight(str) {
return '<span class="myHighlightClass">' + str + '</span>';
}
function escapeHTML(html) {
this.el = this.el || document.createElement('textarea');
this.el.textContent = html;
return this.el.innerHTML;
}
.myHighlightClass {
text-decoration: underline;
color: red;
}
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
<div id="e"></div>
We have a string:
var dynamicString = "This isn't so dynamic, but it will be in real life.";
User types in some input:
var userInput = "REAL";
I want to match on this input, and wrap it with a span to highlight it:
var result = " ... but it will be in <span class='highlight'>real</span> life.";
So I use some RegExp magic to do that:
// Escapes user input,
var searchString = userInput.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
// Now we make a regex that matches *all* instances
// and (most important point) is case-insensitive.
var searchRegex = new RegExp(searchString , 'ig');
// Now we highlight the matches on the dynamic string:
dynamicString = dynamicString.replace(reg, '<span class="highlight">' + userInput + '</span>');
This is all great, except here is the result:
console.log(dynamicString);
// -> " ... but it will be in <span class='highlight'>REAL</span> life.";
I replaced the content with the user's input, which means the text now gets the user's dirty case-insensitivity.
How do I wrap all matches with the span shown above, while maintaining the original value of the matches?
Figured out, the ideal result would be:
// user inputs 'REAL',
// We get:
console.log(dynamicString);
// -> " ... but it will be in <span class='highlight'>real</span> life.";
You'd use regex capturing groups and backreferences to capture the match and insert it in the string
var searchRegex = new RegExp('('+userInput+')' , 'ig');
dynamicString = dynamicString.replace(searchRegex, '<span class="highlight">$1</span>');
FIDDLE
You can use it without capturing groups too.
dynamicString = text.replace(new RegExp(userInput, 'ig'), '<span class="highlight">$&</span>');
There is JQuery.trim() function but it is trimming the white spaces.
But I want to do it like in C#.
string props = ",width=400,height=400,status=0,location=0,";
props.Trim(',');
// result will be: "width=400,height=400,status=0,location=0"
How can I do this? Actually I would like to use it for general input param not only for ','..
Try an regexp:
var props=",width=400,height=400,status=0,location=0,";
props=props.replace(/^[,]*(.*?)[,]*$/, "$1");
If you, for example, also want to remove semicolons at the beginning or the end, use this:
props=props.replace(/^[,;]*(.*?)[,;]*$/, "$1");
And if you want to remove spaces, too, but only at the end:
props=props.replace(/^[,;]*(.*?)[,; ]*$/, "$1");
I found a link do this with functions and I found another link how to add this function to the String type. And I wrote below code and its test link :
String.prototype.TrimLeft = function (chars) {
//debugger;
var re = chars ? new RegExp("^[" + chars + "]+/", "g")
: new RegExp(/^\s+/);
return this.replace(re, "");
}
String.prototype.TrimRight = function (chars) {
var re = chars ? new RegExp("[" + chars + "]+$/", "g")
: new RegExp(/\s+$/);
return this.replace(re, "");
}
String.prototype.Trim = function (chars) {
return this.TrimLeft(chars).TrimRight(chars);
}
^[" + chars + "]+ is finding the characters at the begining of string.
And it is replacing on this line: this.replace(re, "");
With this : [" + chars + "]+$, it is searching characters at the end of string g(globally) and replacing with the same method.
var c=",width=400,height=400,status=0,";
c.Trim(",");
// result: width=400,height=400,status=0