i have a simple smily parser code :
for (var key in smiles) {
text = text.replace(key , smiles[key]);
}
return text;
so the problem is , this will only replace the first one so i've switched to global replace
for (var key in smiles) {
var r = '/'+key+'/g';
console.log(r);
text = text.replace(r , smiles[key]);
}
in console i have :
/:)/g
/;)/g
/:(/g
which seems to be ok , but it wont replace any of these codes :) ;) :(
whats wrong ?
A regular expression literal (/foo/g) is not the same as a string that looks like a regular expression literal ("/foo/g").
You can create regular expressions dynamically using the RegExp constructor:
var r = new RegExp(key, 'g');
And that’s the point at which you’ll get parenthesis-related errors. You can escape your values to put in a regular expression – put together in the nicest way, it might look something like this:
function escapeRegex(text) {
return text.replace(/[[{}()*+?.\\^$|]/g, "\\$&");
}
function replaceAll(str, map) {
var re = new RegExp(Object.keys(map).map(escapeRegex).join("|"), "g");
return str.replace(re, function(m) {
return map[m];
});
}
Just keep looping through the text and replacing the smiley until there are no more occurrences:-
for (var key in smiles) {
while (text.indexOf(key) > -1) {
text = text.replace(key, smiles[key]);
}
}
return text;
Related
I have a JavaScript object such as this:
{
a : {
b : c,
d : e
}
}
In my code, if b my was my starting point, I could input the string "this.$parent.d" which would evaluate to e.
However I could also input the string "this.$parent.b.$parent.d" to get the same result.
My question is if I am given a string such as "this.$parent.b.$parent.d" how can I simplify it to the first way?
I think what I need to do is use regex to replace all occurrences of "$parent.<anything>.$parent" with just "$parent" and that should work but not sure how to do this exactly.
In fact, you'll want to simplify an even shorter expression:
.prop.$parent
Such a substring should be removed, since it is a no-operation.
Here is how you could do that with a regular expression:
function simplify(str) {
const expression = /\.(?!\$parent\.)[\w$]+\.\$parent(?=\.|$)/g;
while (str.length > (str = str.replace(expression, "")).length) {}
return str;
}
var strings = [
"this.$parent.b.$parent.d", // should be this.$parent.d
"this.$parent.b.$parent.d.$parent.b.$parent.b", // should be this.$parent.b
"this.$parent.b.$parent.$parent.b.$parent", // should be this.$parent.$parent
"this.$parent.b.$parent.d.$parent.$parent.b", // should be this.$parent.$parent.b
"this.$parent.b.c.$parent.$parent.b", // should be this.$parent.b
"this.$parentX.b.$parentX", // should be this.$parentX.b.$parentX
];
const results = strings.map(simplify);
console.log(results);
I think the regex you're looking for is this:
/\.\$parent\.[^$]?[^p]?[^a]?[^r]?[^e]?[^n]?[^t]?\.\$parent/g
Someone who is better at regex than me can hopefully simplify this, since it seems very verbose.
The solution below uses a recursive function, because if there are two instances that get replaced in the same string, you have now created another instance of .$parent.*.$parent, which needs to then get replaced with just .$parent.
For example:
this.$parent.b.$parent.d.$parent.$parent.b
After 1 .replace() --> this.$parent.d.$parent.$parent.b
After 2 .replace() --> this.$parent.$parent.b
Here's the code in action:
var expression = /\.\$parent\.[^$]?[^p]?[^a]?[^r]?[^e]?[^n]?[^t]?\.\$parent/g;
var strings = [
"this.$parent.b.$parent.d", // should be this.$parent.d
"this.$parent.b.$parent.d.$parent.b.$parent.b", // should be this.$parent.b
"this.$parent.b.$parent.$parent.b.$parent", // should be this.$parent.$parent
"this.$parent.b.$parent.d.$parent.$parent.b" // should be this.$parent.$parent.b
];
function simplify (str) {
var str = str.replace(expression, ".$parent");
if (expression.test(str)) {
return simplify(str);
}
return str;
}
strings.forEach(function (str) {
console.log(simplify(str));
});
I want to after type Title of post automatically take value and create slug. My code works fine with English Latin characters but problem is when I type characters 'čćšđž'. Code replace first type of this characters in string but if character is repeated than is a problem. So, for testing purpose this title 'šžđčćžđš čćšđžčćšđž čćšđžčć ćčšđžšžčćšđ ćčšžčć' is converted to this slug 'szdcc'.
This is my jquery code:
$('input[name=title]').on('blur', function() {
var slugElement = $('input[name=slug]');
if(slugElement.val()) {
return;
}
slugElement.val(this.value.toLowerCase().replace('ž', 'z').replace('č','c').replace('š', 's').replace('ć', 'c').replace('đ', 'd').replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, ''));
});
How to solve this problems? Also is it possible to this few characters put in same replace() function?
Try this:
function clearText(inp) {
var wrong = 'čćšđž';
var right = 'ccsdz';
var re = new RegExp('[' + wrong + ']', 'ig');
return inp.replace(re, function (m) { return right.charAt(wrong.indexOf(m)); });
}
replace() only replaces the first occurrence unless regex is used with global modifier. You will need to change them all to regular expression.
replace(/ž/g, "z")
As far as I know, it will not be possible to use a single replace() in your case.
If you are concerned with chaining a bunch of .replace() together, you might be better off writing some custom code to replace these characters.
var newStr = "";
for (var i = 0; i < str.length; i++) {
var c = str.charAt(i);
switch (c) {
case "ž": newStr += "z"; break;
default: newStr += c; break;
}
}
I'm trying to transform this string
.jpg,.gif,.png
into this (not dots and space after comma)
jpg, gif, png
I thought that something like PHP's str_replace for arrays in JS will do the trick, so I found this post, and specifically this answer. I tried it but is't not working as expected. I'm getting a blank string... Am I doing something wrong?
JS
String.prototype.replaceArray = function(find, replace)
{
var replaceString = this;
var regex;
for (var i = 0; i < find.length; i++)
{
regex = new RegExp(find[i], "g");
replaceString = replaceString.replace(regex, replace[i]);
}
return replaceString;
};
var my_string = ".jpg,.gif,.png";
alert(my_string.replaceArray([".", ","],["", ", "]));
Link to jsfiddle
The first thing you're trying to replace is a period ("."), which is a regular expression for any character. You need to escape it: "\\."
I just did this:
var target = '.jpg,.gif,.png';
target = target.replace(/\\./g, '');
target = target.replace(/,/g, ', ');
I'm sure it can be done more efficiently, but this will get the job done.
You can change your fn to this :
function strToArr(str)
{
var res = str.replace(/\./g, "");
return res.split(",");
}
I'm trying to do something that would be similar to turning a url slug-like variable into text that could be used for a title.
So, I have a variable for example that is like this:
var thisID = 'athlete-profile';
function myFunc(thisID) {
// i need to use thisID as the id and href in a loop that generates a string of <li><a>'s\
function makeTitle(thisID) {
// convert thisID to text so for this example it would return 'Athlete Profile'
return 'Athlete Profile';
}
for () {
var str = '<li id="'+thisID+'">'+makeTitle(thisID)+'';
}
// make sense?
}
I'd like to not use a regex to do this if possible somehow, but I don't think there's a way to do it without one. So any one who knows how to do this type of thing let me know, it would be a great help.
Thanks
I would advise you to use regular expression. But if you really don't want to use regular expressions, the solution below would work for simple cases. Feel free to modify it as you like it.
function makeTitle(slug) {
var words = slug.split('-');
for (var i = 0; i < words.length; i++) {
var word = words[i];
words[i] = word.charAt(0).toUpperCase() + word.slice(1);
}
return words.join(' ');
}
console.log(
makeTitle("athlete-profile")
)
function titleize(slug) {
var words = slug.split("-");
return words.map(function(word) {
return word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
}).join(' ');
}
console.log(titleize("athlete-profile"))
It works pretty simply:
It splits the string by - into words.
It maps each word into title case.
It joins the resulting words with spaces.
Do it in one line:
'athlete-profile'.split("-").join(" ").replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()})
Output: Athlete Profile
The makeTitle() part of your question can be implemented something like this:
function makeTitle(thisID) {
return thisID.replace(/-/g, " ").replace(/\b[a-z]/g, function() {
return arguments[0].toUpperCase();
});
}
console.log(makeTitle("athlete-profile"))
The first .replace() changes all hyphens to spaces, and then the second .replace() takes any lower-case letter that follows a word boundary and makes it upper-case.
(For more information see the MDN doco for .replace().)
As far as doing it without using regular expressions, I'm not sure why you'd specifically want to avoid them, especially when the required expressions are pretty simple in this case (especially if you do the hyphen to space and first letter capitalisation in two steps as shown above). But there are endless ways to do this without regex using various combinations of JavaScript's string manipulation methods.
Do it like this
let someString = 'im a string';
console.log(someString.replace(/-/g, ' ')
.replace(/\w\S*/g, function (txt) {
return
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
})
)
Output: Im A String
Short and great way:
const slugToText = (slug) => {
return slug.toLowerCase().replace(/-/g,' ')
}
Much Simplified answer
we can use String.prototype.replaceAll method to easily achieve this
function convertSlugToString(slug) {
return slug.replaceAll("-", " ");
}
incase you want to make sure the output is all lowercase then you can do the following
function convertSlugToString(slug) {
return slug.toLowerCase().replaceAll("-", " ");
}
Additional info:
String.prototype.replaceAll() is a ES2021 feature and it also has a great browser support with 93.64% global coverage, click here for more info
if you want to support IE then refer to the other answers
How can I quickly validate if a string is alphabetic only, e.g
var str = "!";
alert(isLetter(str)); // false
var str = "a";
alert(isLetter(str)); // true
Edit : I would like to add parenthesis i.e () to an exception, so
var str = "(";
or
var str = ")";
should also return true.
Regular expression to require at least one letter, or paren, and only allow letters and paren:
function isAlphaOrParen(str) {
return /^[a-zA-Z()]+$/.test(str);
}
Modify the regexp as needed:
/^[a-zA-Z()]*$/ - also returns true for an empty string
/^[a-zA-Z()]$/ - only returns true for single characters.
/^[a-zA-Z() ]+$/ - also allows spaces
Here you go:
function isLetter(s)
{
return s.match("^[a-zA-Z\(\)]+$");
}
If memory serves this should work in javascript:
function containsOnlyLettersOrParenthesis(str)
(
return str.match(/^([a-z\(\)]+)$/i);
)
You could use Regular Expressions...
functions isLetter(str) {
return str.match("^[a-zA-Z()]+$");
}
Oops... my bad... this is wrong... it should be
functions isLetter(str) {
return "^[a-zA-Z()]+$".test(str);
}
As the other answer says... sorry