Regex: match last and second-last character - javascript

I need to wrap the two last characters in a string in a separate <span>:
-1:23 // This is what I have
-1:<span>2</span><span>3</span> // This is what I want
The following matches the last character – but how can I make it match the second last as well?
str.replace(/(.$)/, "<span>$1</span>");
Thanks :)

You may use
.replace(/.(?=.?$)/g, "<span>$&</span>")
See the regex demo
If these must be digits, replace . with \d:
.replace(/\d(?=\d?$)/g, "<span>$&</span>")
The pattern matches
\d - a digit
(?=\d?$) - that is followed with an end of string or a digit and end of string.
The $& is a replacement backreference that references the whole match value from the string replacement pattern.
JS demo:
console.log("-1:23".replace(/.(?=.?$)/g, "<span>$&</span>"));
console.log("-1:23".replace(/\d(?=\d?$)/g, "<span>$&</span>"));
Now, to make it more dynamic, you may use a limiting (range/interval) quantifier:
function wrap_chars(text, num_chars) {
var reg = new RegExp(".(?=.{0," + (num_chars-1) + "}$)", "g");
return text.replace(reg, "<span>$&</span>");
}
console.log(wrap_chars("-1:23", 1)); // wrap one char at the end with span
console.log(wrap_chars("-1:23", 2)); // wrap two chars at the end with span

You can add another group before the last one, which also matches a single character ((.)), then wrap each of them using references ($1 and $2):
var str = '-1:23'.replace(/(.)(.)$/, '<span>$1</span><span>$2</span>')
console.log(str);

Related

regex replace only a part of the match

I want to replace only a part of the string of a regex pattern match. I found this answer but I don't get it...
How do I use substitution?
Example of what I want: keep the first slug digit, only replace others
/09/small_image/09x/ > /09/thumbnail/
1st: unknown digit
2nd: "small_image"
3rd: unknown digit + "x"
Here is what I have so far:
var regexPattern = /\/\d\/small\_image\/\d*x/;
var regexPattern = /\/\d\/(small\_image\/\d*x)$1/; ??
var result = regexPattern.test(str);
if (result) {
str = str.replace(regexPattern, 'thumbnail');
}
var input = "/09/small_image/09x/";
var output = input.replace(/(\/\d+\/)small_image\/\d*x/, "$1thumbnail");
console.log(output);
Explanation:
Put the part you want to keep in parentheses, then refer to that as $1 in the replacement string - don't put $1 in your regex. So (\/\d+\/) means to match a forward slash followed by one or more digits, followed by another forward slash.
(Note that you don't need to escape underscores in a regex.)
Go with
var regexPattern = /(\/\d+\/)small\_image\/\d*x/;
and
str = str.replace(regexPattern, '$1thumbnail');
First, you were missing the +. Because 09 are two digits, you need the regexp to match one or more digits (\ḑ would be exactly one). This is accomplished by \d+
Second, everything you match is being removed at first. To get the /09/ part back afterwards, you have to remember it by putting it into brackets in the regexp (...) and afterwards reference it in the replacement via $1
One could as well create other groups and reference them by $2,$3 ...

Regexp in Javascript: replace minus with comma+minus when condition is met

I need to replace \- minus with \,+- comma+minus when space/no-space/comma before the minus. In a SVG path I found this:
`201.86-38.778`
and I need to make it
`201.86,-38.778`.
I tried str.replace(/-/g,'\,-') but this creates additional commas when not needed.
Update, I also need this to work like this:
`201.86 -38.778` // notice the space
to make it
`201.86,-38.778`.
You can use
/(^|[^,\s])-/g
See the regex demo
Breakdown:
(^|[^,\s]) - match and capture the start of string or a character other than a comma or whitespace (that will be referenced to with the $1 backreference in the replacement pattern)
- - a literal hyphen.
In the replacement pattern, use $1,-, a backreference to the captured text + comma and a hyphen.
Demo:
var re = /(^|[^,\s])-/g;
var str = '201.86-38.778';
var result = str.replace(re, '$1,-');
document.body.innerHTML = result;
Find with ([-+]) and replace with ,\1. Regex101 Demo

Regular Expression for changing chars of the words in string to underscore except First char

I'm trying to find a regular expression which modifies the single words in a string containing underscore except the first character.
Example: This is a Test. => T___ i_ a T___.
I'm come up with: (\w)\w*/g which results in T i a T. But I don't know how to get the underscores in place.
Thanks.
This should work:
"This is a Test".replace(/\B\w/g, "_")
Explanation: replace every word character, unless it's preceded by a non-word char.
The naively correct version of your attempt would be
var wordMatch = /\b(\w)(\w+)/g;
input.replace(wordMatch, function ($0, $1, $2) {
return $1 + (new Array($2.length)).join('_');
});
However, this does not work with words that have accented characters, because \w only includes the ASCII range (a-z) and it includes the underscore, which strictly speaking is not a word character.
A more correct version would take set of Unicode ranges in place of \w:
var latinRanges = "\\u0041-\\u005a\\u0061-\\u007a\\u0100-\\u01bf\\u01c4-\\u024f";
wordMatch = new RegExp("(?:^|[^" + latinRanges + "])([" + latinRanges + "])([" + latinRanges + "]+)", "g");
input.replace(wordMatch, function ($0, $1, $2) {
return $1 + (new Array($2.length)).join('_');
});
The ranges \u0041-\u005a, \u0061-\u007a, \u0100-\u01bf and \u01c4-\u024f include every character in the extended Latin alphabet (basic forms, accented forms, upper- and lowercase forms).
You could do like this,
> var s = 'This is a Test.'
> s.replace(/((?:^|\s)\w)(\w*)/g, function(x,y,z) {return y+z.replace(/./g, '_')});
'T___ i_ a T___.'
((?:^|\s)\w) regex captures the first word character along with the preceding space or start of the line boundary.
(\w*) captures the following zero or more word characters.
So the whole match was referred by the first functional parameter x then the chars inside the first captured group was referred by y and the chars inside second captured group was referred by z.
Now the whole match was replaced by ,
y -> chars inside first capturing group.
Plus
z.replace(/./g, '_') will replace each char present inside the second capturing group with _ symbol. Then the final result was concatenated with y and forms the final replacement string.
Your regular expression, as you say mtaches the word. To replace the letters with _ use the replace variant with a function parameter:
var sentence = "Now is the time for all good men";
var cached = sentence.replace (/(\w)(\w*)/g,
function (_,initial, rest) {
return initial + rest.replace (/./g, '_');
});

regex string replace

I am trying to do a basic string replace using a regex expression, but the answers I have found do not seem to help - they are directly answering each persons unique requirement with little or no explanation.
I am using str = str.replace(/[^a-z0-9+]/g, ''); at the moment. But what I would like to do is allow all alphanumeric characters (a-z and 0-9) and also the '-' character.
Could you please answer this and explain how you concatenate expressions.
This should work :
str = str.replace(/[^a-z0-9-]/g, '');
Everything between the indicates what your are looking for
/ is here to delimit your pattern so you have one to start and one to end
[] indicates the pattern your are looking for on one specific character
^ indicates that you want every character NOT corresponding to what follows
a-z matches any character between 'a' and 'z' included
0-9 matches any digit between '0' and '9' included (meaning any digit)
- the '-' character
g at the end is a special parameter saying that you do not want you regex to stop on the first character matching your pattern but to continue on the whole string
Then your expression is delimited by / before and after.
So here you say "every character not being a letter, a digit or a '-' will be removed from the string".
Just change + to -:
str = str.replace(/[^a-z0-9-]/g, "");
You can read it as:
[^ ]: match NOT from the set
[^a-z0-9-]: match if not a-z, 0-9 or -
/ /g: do global match
More information:
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
Your character class (the part in the square brackets) is saying that you want to match anything except 0-9 and a-z and +. You aren't explicit about how many a-z or 0-9 you want to match, but I assume the + means you want to replace strings of at least one alphanumeric character. It should read instead:
str = str.replace(/[^-a-z0-9]+/g, "");
Also, if you need to match upper-case letters along with lower case, you should use:
str = str.replace(/[^-a-zA-Z0-9]+/g, "");
str = str.replace(/\W/g, "");
This will be a shorter form
We can use /[a-zA-Z]/g to select small letter and caps letter sting in the word or sentence and replace.
var str = 'MM-DD-yyyy'
var modifiedStr = str.replace(/[a-zA-Z]/g, '_')
console.log(modifiedStr)

regex match text in between

I get strings like:
"some text here /word/ asdhd"
"some other likehere/word1/hahas"
"some other likehere/dhsad huasdhuas huadssad/h ah as/"
What I need is to get the string between the two slashes, 'word', 'word1', 'dhsad huasdhuas huadssad' and 'h ah as'.
What is a regex for that?
Edit in case you have more than one of those words and want to iterate through them.
*Edit again since question was changed.*
var myregexp = /\/(.+?)(?=\/)/g;
var match = myregexp.exec(subject);
while (match != null) {
// matched text: match[1]
match = myregexp.exec(subject);
}
Explanation :
// \/(.+?)(?=\/)
//
// Match the character “/” literally «\/»
// Match the regular expression below and capture its match into backreference number 1 «(.+?)»
// Match any single character that is not a line break character «.+?»
// Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?»
// Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\/)»
// Match the character “/” literally «\/»
var string = "some other likehere/dhsad huasdhuas huadssad/h ah as/";
var matches = string.match(/[/](.*)[/]/)[1];
That should do it.
EDIT revised to match new criteria.
\/[a-zA-Z0-9]+\/
\/ matches slashes
[a-zA-Z0-9] matches any letters uppercase or lower, and any numbers
+ means one or more
"some text here /word/ asdhd".match(/\/(.+)\//)
If you want to match more than one occurence in the same string, you need to use exec. See #FailedDev's answer.

Categories