Replace all “?” by “&” except first - javascript

I’d would to replace all “?” by “&” except the first one by javascript. I found some regular expressions but they didn’t work.
I have something like:
home/?a=1
home/?a=1?b=2
home/?a=1?b=2?c=3
And I would like:
home/?a=1
home/?a=1&b=2
home/?a=1&b=2&c=3
Someone know how to I can do it?
Thanks!

I don't think it's possible with regex but you can split the string and then join it back together, manually replacing the first occurance:
var split = 'home/?a=1?b=2'.split('?'); // [ 'home/', 'a=1', 'b=2' ]
var replaced = split[0] + '?' + split.slice(1).join('&') // 'home/?a=1&b=2'
console.log(replaced);

You could match from the start of the string not a question mark using a negated character class [^?]+ followed by matching a question mark and capture that in the first capturing group. In the second capturing group capture the rest of the string.
Use replace and pass a function as the second parameter where you return the first capturing group followed by the second capturing group where all the question marks are replaced by &
let strings = [
"home/?a=1",
"home/?a=1?b=2",
"home/?a=1?b=2?c=3"
];
strings.forEach((str) => {
let result = str.replace(/(^[^?]+\?)(.*)/, function(match, group1, group2) {
return group1 + group2.replace(/\?/g, '&')
});
console.log(result);
});

You can split it by "?" and then rewrap the array:
var string = "home/?a=1?b=2";
var str = string.split('?');
var new = str[0] + '?'; // text before first '?' and first '?'
for( var x = 1; x < str.length; x++ ) {
new = new + str[x];
if( x != ( str.length - 1 ) ) new = new + '&'; //to avoid place a '&' after the string
}

You can use /([^\/])\?/ as pattern in regex that match any ? character that isn't after / character.
var str = str.replace(/([^\/])\?/g, "$1&");
var str = "home/?a=1\nhome/?a=1?b=2\nhome/?a=1?b=2?c=3\n".replace(/([^\/])\?/g, "$1&");
console.log(str);

Related

Replace nth occurrence javascript

in this example string '1,2,3,4,5' I am trying to capture and replace the 3rd occurence of the comma , character
this code here
'1,2,3,4,5'.match(/(?:[^,]*,){2}[^,]*(,)/)
matches 1,2,3 and the comma im looking for
but not sure how to replace just the comma
'1,2,3,4,5'.replace(/(?:[^,]*,){2}[^,]*(,)/, "$")
replaces everything before 4 giving $4,5
i just want a string result like 1,2,3$4,5 for example
I have achieved this task in two different ways, with array split and slice and with a String#replace that takes a callback
//splice
let parts = [];
let str = "1,2,3,4,5";
let formatted = ((parts = str.split(",")).slice(0,3)).join("-") + ' ' + parts.slice(3).join(":")
​
//callback
let str = "1,2,3,4,5";
str.replace(/,/g, (() => {
let count = 0;
return (match, position) => {
count += 1;
if(count == 3) return ' ';
else if(count < 3) return '-';
else return ':';
});
})())
Is this even possible with a plain String#replace?
You can use capturing group and replace by first capturing group
.replace(/((?:[^,]*,){2}[^,]*),/g, "$1:");
^ ^
The captured group will capture the matched string except the third comma which is $1 in the replacement string.
console.log('1,2,3,4,5,2,3,4,5,2,3,4,5'.replace(/((?:[^,]*,){2}[^,]*),/g, "$1:"));

String that doesn't contain character group

I wrote regex for finding urls in text:
/(http[^\s]+)/g
But now I need same as that but that expression doesn't contain certain substring, for instance I want all those urls which doesn't contain word google.
How can I do that?
Here is a way to achieve that:
http:\/\/(?!\S*google)\S+
See demo
JS:
var re = /http:\/\/(?!\S*google)\S+/g;
var str = 'http://ya.ru http://yahoo.com http://google.com';
var m;
while ((m = re.exec(str)) !== null) {
document.getElementById("r").innerHTML += m[0] + "<br/>";
}
<div id="r"/>
Regex breakdown:
http:\/\/ - a literal sequence of http://
(?!\S*google) - a negative look-ahead that performs a forward check from the current position (i.e. right after http://), and if it finds 0-or-more-non-spaces-heregoogle the match will be cancelled.
\S+ - 1 or more non-whitespace symbols (this is necessary since the lookahead above does not really consume the characters it matches).
Note that if you have any punctuation after the URL, you may add \b right at the end of the pattern:
var re1 = /http:\/\/(?!\S*google)\S+/g;
var re2 = /http:\/\/(?!\S*google)\S+\b/g;
document.write(
JSON.stringify(
'http://ya.ru, http://yahoo.com, http://google.com'.match(re1)
) + "<br/>"
);
document.write(
JSON.stringify(
'http://ya.ru, http://yahoo.com, http://google.com'.match(re2)
)
);

JavaScript Regular expression replace except first and last

I want to write a regular expression in JavaScript . So string can be replaced but except first and last one.
e.g.
str="'Marys' Home'"
I want regular expression in JavaScript so output can be :
"'Marys\' Home'"
i.e except first and last one single quote ' replaced by \'.
Similar solution in Python I found: Regular expression replace except first and last characters
You can use this:
var str = "'Marys' Home'";
var result = str.replace(/(?!^)(')(?!$)/g, '\\$1');
//=> 'Marys\' Home'
RegEx Demo
var str = "'Marys' Home'"
function replace(str, pattern, replacement) {
var firstIndex = str.indexOf(pattern)
, lastIndex = str.lastIndexOf(pattern)
, re = new RegExp(pattern, 'g')
if (firstIndex < lastIndex)
str = str.substr(firstIndex + pattern.length, lastIndex)
return str.replace(re, replacement)
}
console.log(replace(str, "'", "\'"))
Something like this you are looking for?

Live replacement for regular expressions with Javascript

I'm writing a code for live replacement of specific words in a text field as the user types.
I'm using regex and javascript:
The first array has the regular expressions to be found, and the second array has the words that should replace any them.
source = new Array(/\srsrs\s/,/\sñ\s/,/\snaum\s/,/\svc\s/,/\scd\s/,/\sOq\s/,/\soke\s/,/\so\sq\s/,
/\soque\s/,/\soqe\s/,/\spq\s/,/\sq\s/,/\sp\/\s/g,/\spra\s/,/\sp\s/,/\stbm\s/,
/\stb\s/,/\std\s/,/\sblz\s/,/\saki\s/,/\svlw\s/,/\smara\s/,/\sqlq\s/,/\sqq\s/,
/\srpz\s/,/\smsm\s/,/\smto\s/,/\smtu\s/,/\sqro\s/,/\sqdo\s/,/\sqd\s/,/\sqnd\s/,
/\sqto\s/,/\sqm\s/,/\sjah\s/, /\sc\/\s/,/\scmg\s/,/\s\+\sou\s\-\s/,/\sflw\s/,
/\sxau\s/,/\sto\s/,/\sta\s/);
after = new Array("risos","não","não","você","cadê","o que","o que","o que","o que","o que","porque",
"que","para","para","para","também","também","tudo","beleza","aqui","valeu","maravilhoso",
"qualquer","qualquer","rapaz","mesmo","muito","muito","quero","quando","quando","quando",
"quanto","quem","Já","com","comego","mais ou menos","falow","tchau","estou","está");
This is the function that does the replacement:
function replacement(){
for(i=0; i<source.length; i++){
newtext = " "+document.getElementById("translation").value+" ";
console.log(newtext);
if(myregex = newtext.match(source[i])){
newafter = after[i];
rafael = myregex+" ";
document.getElementById("translation").value = document.getElementById("translation").value.replace(rafael, newafter);
}
}
}
My problem is every time the function is called to replace an expression with only one letter, the replacement is being made on the first occurrence of that letter, even within a word. I thought looking for that letter with \s before and after would solve it, but it didn't.
If you're looking only to match a word, you should put \b before and after (word boundary). This will ensure that you don't match parts of words. Also note that you are corrupting your regex by concatenating a string. Try this instead:
var in = document.getElementById("translation").value;
if( in.charAt(in.length-1) == " ") { // user has just finished typing a word
// this avoids interrupting the word being typed
var l = source.length, i;
for( i=0; i<l; i++) in = in.replace(source[i],after[i]);
document.getElementById("translation").value = in;
}
You need to add a g (global) modified to regexes so that it will replace all occurrences and use \b instead of \s to mark word boundaries.
source = new Array(/\brsrs\b/g,/\bñ\b/g, etc
On a side note, since all your regexes follow the same pattern it might be easier to just do:
source = new Array( 'rsr', 'ñ', 'naum', etc );
if( myregex = newtext.match( new Regexp( "\b"+source[i]+"\b", 'g' ) ) ) {
...
If by "live replacement" you mean calling function replacement at each keystroke then \b at the end will not help you, you should indeed use \s. However in your replacement function your are adding a space to the text field value so your single character words are triggering the replacement.
Here is my refactoring of your code :
(function () { // wrap in immediate function to hide local variables
source = [ [/\brsrs\s$/, "risos"], // place reg exp and replacement next to each other
[/\b(ñ|naum)\s$/, "não"], // note combined regexps
[/\bvc\s$/, "você"]
// ...
]; // not also use of array literals in place of new Array
document.getElementById ("translation"​​​​​​​).addEventListener ('keyup', function (ev) {
var t = this.value // fetch text area value
, m
, i = source.length;
while (i--) // for each possible match
if ((m = t.match(source[i][0]))) { // does this one match ?
// replace match : first remove the match string (m[0]) from the end of
// the text string, then add the replacement word followed by a space
this.value = t.slice (0, -m[0].length) + source[i][1] + ' ';
return; // done
}
}, false);
}) ();​
And the fiddle is : http://jsfiddle.net/jFYuV
In a somewhat different style, you could create a function that encapsulated the list of substitutions:
var substitutions = {
"rsrs": "risos",
"ñ": "não",
"naum": "não",
"vc": "você",
// ...
};
var createSubstitutionFunction = function(subs) {
var keys = [];
for (var key in subs) {
if (subs.hasOwnProperty(key)) {
keys[keys.length] = key;
}
}
var regex = new RegExp("\\b" + keys.join("\\b|\\b") + "\\b", "g");
return function(text) {
return text.replace(regex, function(match) {
return subs[match];
});
};
};
var replacer = createSubstitutionFunction(substitutions);
You would use it like this:
replacer("Some text with rsrs and naum and more rsrs and vc")
// ==> "Some text with risos and não and more risos and você"

How to combine 2 conditions and more in regex

I want to create a regex that match '.', '#' and ':' and also match everything inside these brackets '[' & ']' such as [foo] & [bar]
I already have this match string.match(/[.#:]/g) for '.','#' and ':'.
I know that the brackets regex should look like this \[.\]
but how do I combine them both to one condition?
thanks,
Alon
to combine them use
/[.#:]|(?:\[.+?\])/g
?: is optional and is used to not capture the group (anything in parenthesis)
UPDATE:
.+? (one or more) or .*?(for zero or more)- use this for lazy matching, otherwise [ sdfsdf][sdfsddf ] will be matched
var s = "a . b # c : d [foo]";
var m = /[.:#]|\[.*?\]/g;
s.match(m);
// returns [".", "#", ":", "[foo]"]
var data = '[content]kjalksdjfa.sdf[sc.tt].#:';
var myregexp = /(\[.+?\])|[.#:]/g;
var match = myregexp.exec(data);
var result = "Matches:\n";
while (match != null) {
result += "match:"+match[0] + ',\n';
match = myregexp.exec(data);
}
alert(result);

Categories

Resources