Match last character, get next to last if regex is null - javascript

I'm trying to get the last character of a string, but only if it matches the following RegEx:
/\W/
If it doesn't match, I want it to move to the next last character and do the test again until it finds a match.
function getLastChar(s) {
var l = s.length - 1;
return s[l - i]; // need logic to keep checking for /\W/
}
getLastChar('hello.'); // returns '.', want it to return 'o'
I have the following idea of how to match if the character isn't a letter/number; however, I'm searching for a more elegant solution, one that would allow me to return the last matching character on a single line with a ternary if()
if(string.match(/\W/) !== null){
//keep looking for a match, going backwards.
}

/(\w)\W*$/
Capture one \w character, that is followed by zero or more \W characters, anchored to the end of the subject.
[Edited after comments.]

Easy enough.. just do a greedy match up to the last \W
string.match(/.*(\W)/)

If you're looking for a simple answer, you might be able to accomplish it with a single regex, no looping required - something like the following:
^.*(\W)[^\W]*$
The capture group will have the last non-word character.
For example, running this regex on ~~~~99*9 puts the character * in the capture group.
Edit:
However, after re-reading your question, it seems like you really meant to use \w not \W - in other words, you want the last word character, not the last non-word character. That's easily fixed by swapping \W for \w in the regex above.

Related

RegExp: How to find only one match (or not match pattern)

I can't get how to write regexp right to be able match only heo. So for example if we found some l
char during parsing - cancel that match then.
'heo heo helo'.match(/he.*(?!l)o/gi) // should be only [heo, heo]
UPD:
I need to match as mutch as possible times among the string. Not the first one. Thanks
Example (wrong one):
console.log('heo heo helo'.match(/he.*(?!l)o/gi))
There are two issues:
.* - matches any zero or more chars other than line break chars as many as possible, and thus will match till the last occurrence of the subsequent patterns in the regex. You might use a non-greedy .*? here to fix the issue.
(?!l)o - always matches o, since o is not l, (?!l), a negative lookahead, always returns true, saying, yes, go ahead and return the match. You wanted a negative lookbehind, (?<!l) here.
To match strings starting with he and then matching any chars (other than line break chars) as few as possible and then o not preceded with l, you can use
/he.*?(?<!l)o/gi
See this regex demo. The .*?(?<!l)o pattern matches any 0+ chars other than line break chars as few as possible up to the leftmot o that is not immediately preceded with l.
Now, if you just want to match words that start with he and end with o not preceded with l, you can use
/\bhe[a-z]*(?<!l)o\b/gi
/\bhe(?![a-z]*lo\b)[a-z]*o\b/gi
See this regex demo and this regex demo.
console.log('heo heo helo'.match(/he.*(?!l)o/gi))
You matches any characters .* before checking the condition (?!l). Your regex should check condition before matching characters.
Besides, you want to match only hexxxo (x is not l), so you should use \b in your regex. I suggest following regex.
console.log('heo heo helo aheob'.match(/\bhe[^l]*o\b/gi));

How to match one 'x' but not one or both of xs in 'xx' globally in string [duplicate]

Not quite sure how to go about this, but basically what I want to do is match a character, say a for example. In this case all of the following would not contain matches (i.e. I don't want to match them):
aa
aaa
fooaaxyz
Whereas the following would:
a (obviously)
fooaxyz (this would only match the letter a part)
My knowledge of RegEx is not great, so I am not even sure if this is possible. Basically what I want to do is match any single a that has any other non a character around it (except for the start and end of the string).
Basically what I want to do is match any single a that has any other non a character around it (except for the start and end of the string).
^[^\sa]*\Ka(?=[^\sa]*$)
DEMO
\K discards the previously matched characters and lookahead assertes whether a match is possibel or not. So the above matches only the letter a which satifies the conditions.
OR
a{2,}(*SKIP)(*F)|a
DEMO
You may use a combination of a lookbehind and a lookahead:
(?<!a)a(?!a)
See the regex demo and the regex graph:
Details
(?<!a) - a negative lookbehind that fails the match if, immediately to the left of the current location, there is a a char
a - an a char
(?!a) - a negative lookahead that fails the match if, immediately to the right of the current location, there is a a char.
You need two things:
a negated character class: [^a] (all except "a")
anchors (^ and $) to ensure that the limits of the string are reached (in other words, that the pattern matches the whole string and not only a substring):
Result:
^[^a]*a[^a]*$
Once you know there is only one "a", you can use the way you want to extract/replace/remove it depending of the language you use.

How to extract the last word in a string with a JavaScript regex?

I need is the last match. In the case below the word test without the $ signs or any other special character:
Test String:
$this$ $is$ $a$ $test$
Regex:
\b(\w+)\b
The $ represents the end of the string, so...
\b(\w+)$
However, your test string seems to have dollar sign delimiters, so if those are always there, then you can use that instead of \b.
\$(\w+)\$$
var s = "$this$ $is$ $a$ $test$";
document.body.textContent = /\$(\w+)\$$/.exec(s)[1];
If there could be trailing spaces, then add \s* before the end.
\$(\w+)\$\s*$
And finally, if there could be other non-word stuff at the end, then use \W* instead.
\b(\w+)\W*$
In some cases a word may be proceeded by non-word characters, for example, take the following sentence:
Marvelous Marvin Hagler was a very talented boxer!
If we want to match the word boxer all previous answers will not suffice due the fact we have an exclamation mark character proceeding the word. In order for us to ensure a successful capture the following expression will suffice and in addition take into account extraneous whitespace, newlines and any non-word character.
[a-zA-Z]+?(?=\s*?[^\w]*?$)
https://regex101.com/r/D3bRHW/1
We are informing upon the following:
We are looking for letters only, either uppercase or lowercase.
We will expand only as necessary.
We leverage a positive lookahead.
We exclude any word boundary.
We expand that exclusion,
We assert end of line.
The benefit here are that we do not need to assert any flags or word boundaries, it will take into account non-word characters and we do not need to reach for negate.
var input = "$this$ $is$ $a$ $test$";
If you use var result = input.match("\b(\w+)\b") an array of all the matches will be returned next you can get it by using pop() on the result or by doing: result[result.length]
Your regex will find a word, and since regexes operate left to right it will find the first word.
A \w+ matches as many consecutive alphanumeric character as it can, but it must match at least 1.
A \b matches an alphanumeric character next to a non-alphanumeric character. In your case this matches the '$' characters.
What you need is to anchor your regex to the end of the input which is denoted in a regex by the $ character.
To support an input that may have more than just a '$' character at the end of the line, spaces or a period for instance, you can use \W+ which matches as many non-alphanumeric characters as it can:
\$(\w+)\W+$
Avoid regex - use .split and .pop the result. Use .replace to remove the special characters:
var match = str.split(' ').pop().replace(/[^\w\s]/gi, '');
DEMO

Regular expression to retrieve from the URL

/test-test-test/test.aspx
Hi there,
I am having a bit difficult to retrieve the first bit out from the the above URL.
test-test-test
I tried this /[\w+|-]/g but it match the last test.aspx as well.
Please help out.
Thanks
One way of doing it is using the Dom Parser as stated here: https://stackoverflow.com/a/13465791/970247.
Then you could access to the segments of the url using for example: myURL.segments; // = Array = ['test-test-test', 'test.aspx']
You need to use a positive lookahead assertion. | inside a character class would match a literal | symbol. It won't act like an alternation operator. So i suggest you to remove that.
[\w-]+(?=\/)
(?=\/) called positive lookahead assertion which asserts that the match must be followed by an forward slash. In our case test-test-test only followed by a forward slash, so it got matched. [\w-]+ matches one or more word character or hyphen. + repeats the previous token one or more times.
Example:
> "/test-test-test/test.aspx".match(/[\w-]+(?=\/)/g)
[ 'test-test-test' ]
[\w+|-] is wrong, should be [\w-]+. "A series of characters that are either word characters or hyphens", not "a single character that is a word character, a plus, a pipe, or a hyphen".
The g flag means global match, so naturally all matches will be found instead of just the first one. So you should remove that.
> '/test-test-test/test.aspx'.match(/[\w-]+/)
< ["test-test-test"]

How to match with an exact string using regular expression

I have small requirement.I want to search a string with exact match.
Suppose i want to search for None_1, i am searching for 'None_1' using /None_1/, but it is matching even "xxxNone" but my requirement is it should match only None_[any digit].
Here is my code
/^None_+[0-9]{?}/
So it should match only None_1 , None_2
You should also anchor the expression at the end of the line. But that alone will not make it work. Your expression is wrong. I think it should be:
/^None_[0-9]+$/
^ matches the beginning of a line
[0-9]+ matches one or more digits
None_ matches None_
$ matches the end of a line
If you only want to match one digit, remove the +.
Your original expression /^None_+[0-9]{?}/ worked like this:
^ matches the beginning of a line
None matches None
_+ matches one or more underscores
[0-9] matches one digit
{? matches an optional opening bracket {
} matches }
Try this:
/^None_+[0-9]{?}$/

Categories

Resources