How can I match a substring only if it is not proceeded by a space?
In the string below, I want to match only the first and third lines and not the second. In this case the line also needs to start with a #
#match
#not match
#match
https://regex101.com/r/VE3Q8z/1
The negative lookahead (?! ) doesn't seem to affect anything. Maybe what I'm looking for is a negative look-behind, but I haven't found any examples (that make sense to me) on how do do so in Javascript.
You could achieve it with anchors:
^(?! )(#+)(.*)
See the afore-mentionned link to your own demo: https://regex101.com/r/VE3Q8z/2
Just use an anchor to verify that the string starts with a "#". And then add the "global" and "multiline" flags to it
/^#+(.*)/gm
https://regex101.com/r/koOXUB/1
This is your regex :
^#(.*)
this part ^# match with all string that begin by #. You can modify the last part to match only character or number..
Related
I use this regex
/\.(.+)?(?=(\(?)|\r\n)/gi
with
part1.part2
part1.part2(part3) part4
I want only match .part2 in both cases
but in second case I get .part2(part3) part4
You should make the .+ part non-greedy, by using .+?, as otherwise it will also capture the opening parenthesis you want to see in the look-ahead part.
Also, in the second part, don't make the \( optional, otherwise you will be OK in having nothing in your look-ahead to match.
Finally, don't match \r\n, but the end-of-line anchor $ in combination with the m flag (so that it matches the end of each line instead of the whole input).
So:
\.(.+?)(?=\(|$)
regex101 link
You see the parenthesis in the match as the . can also match (.
The pattern will match the rest of the line after the first dot without backtracking to a ( as the parenthesis in the lookahead is optional \(? and the assertion will be true.
You could make use of a negated character class not crossing parenthesis or a newline when matching.
\.([^()\r\n]+)
Regex demo
I have a string which looks like
var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42)
.ramBam(8.1, 0).bam(8.1, (slot_height-thick)/2)
I want to put a tag around the last .bam() or .ramBam().
str.replace(/(\.(ram)?bam\(.*?\))$/i, '<span class="focus">$1</span>');
And I hope to get:
new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42).ramBam(8.1, 0)<span class="focus">.bam(8.1, (slot_height-thick)/2)</span>
But somehow I keep on fighting with the non greedy parameter, it wraps everything after new Bammer with the span tags. Also tried a questionmark after before the $ to make the group non greedy.
I was hoping to do this easy, and with the bam or ramBam I thought that regex would be the easiest solution but I think I'm wrong.
Where do I go wrong?
You can use the following regex:
(?!.*\)\.)(\.(?:bam|ramBam)\(.*\))$
Demo
(?!.*\)\.) # do not match ').' later in the string
( # begin capture group 1
.\ # match '.'
(?:bam|ramBam) # match 'bam' or 'ramBam' in non-cap group
\(.*\) # match '(', 0+ chars, ')'
) # end capture group 1
$ # match end of line
For the example given in the question the negative lookahead (?!.*\)\.) moves an internal pointer to just before the substring:
.bam(8.1, (slot_height-thick)/2)
as that is the first location where there is no substring ). later in the string.
If there were no end-of-line anchor $ and the string ended:
...0).bam(8.1, (slot_height-thick)/2)abc
then the substitution would still be made, resulting in a string that ends:
...0)<span class="focus">.bam(8.1, (slot_height-thick)/2)</span>abc
Including the end-of-line anchor prevents the substitution if the string does not end with the contents of the intended capture group.
Regex to use:
/\.((?:ram)?[bB]am\([^)]*\))(?!.*\.(ram)?[bB]am\()/
\. Matches period.
(?:ram)? Optionally matches ram in a non-capturing group.
[bB]am Matches bam or Bam.
\( Matches (.
[^)]* Matches 0 or more characters as long as they are not a ).
) Matches a ). Items 2. through 6. are placed in Capture Group 1.
(?!.*\.(ram)?[bB]am\() This is a negative lookahead assertion stating that the rest of the string contains no further instance of .ram( or .rambam( or .ramBam( and therefore this is the last instance.
See Regex Demo
let str = 'var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, 0).bam(0, -42).ramBam(8.1, 0).bam(8.1, slot_height)';
console.log(str.replace(/\.((?:ram)?[bB]am\([^)]*\))(?!.*\.(ram)?[bB]am\()/, '<span class="focus">.$1</span>'));
Update
The JavaScript regular expression engine is not powerful enough to handle nested parentheses. The only way I know of solving this is if we can make the assumption that after the final call to bam or ramBam there are no more extraneous right parentheses in the string. Then where I had been scanning the parenthesized expression with \([^)]*\), which would fail to pick up final parentheses, we must now use \(.*\) to scan everything until the final parentheses. At least I know no other way. But that also means that the way that I had been using to determine the final instance of ram or ramBam by using a negative lookahead needs a slight adjustment. I need to make sure that I have the final instance of ram or ramBam before I start doing any greedy matches:
(\.(?:bam|ramBam)(?!.*\.(bam|ramBam)\()\((.*)\))
See Regex Demo
\. Matches ..
(?:bam|ramBam) Matches bam or ramBam.
(?!.*\.(bam|ramBam)\() Asserts that Item 1. was the final instance
\( Matches (.
(.*) Greedily matches everything until ...
\) the final ).
) Items 1. through 6. are placed in Capture Group 1.
let str = 'var std = new Bammer({mode:"deg"}).bam(0, 112).bam(177.58, (line-4)/2).bam(0, -42) .ramBam(8.1, 0).bam(8.1, (slot_height-thick)/2)';
console.log(str.replace(/(\.(?:bam|ramBam)(?!.*\.(bam|ramBam)\()\((.*)\))/, '<span class="focus">$1</span>'));
The non-greedy flag isn't quite right here, as that will just make the regex select the minimal number of characters to fit the pattern. I'd suggest that you do something with a negative lookahead like this:
str.replace(/(\.(?:ram)?[Bb]am\([^)]*\)(?!.*(ram)?[Bb]am))/i, '<span class="focus">$1</span>');
Note that this will only replace the last function name (bam OR ramBam), but not both. You'd need to take a slightly different approach to be able to replace both of them.
I want to match exactly one occurrence of # in a string. I found that /^[^#]+#[^#]+$/ working but not /[^#]+#[^#]+/
Why should I include the search from beginning to end? Wont the pattern anyway check throughout the string? Can someone explain it for me?
Without providing ^ and $, your RegEx will match parts of your string.
Let's demonstrate with some examples :
/^[^#]+#[^#]+$/
matches test#String.
doesn't match test#Str#ing
/[^#]+#[^#]+/
matches test#String
matches the part test#Str of test#Str#ing
Can anyone help me with the REGEX to match
../_assets/applications/cleaning/*logo.png
"*" being the file name which can also follow an underscore or dash so
../_assets/applications/cleaning/main_logo.png
OR
../_assets/applications/cleaning/main-logo.png
this is as far as I got
\assets\/applications\/cleaning\/
An asterisk in a regex is a quantifier allowing zero or more of the previous character/group. So you first expression would allow zero or more forward slashes. You can use a . with a * to allow for zero or more of any character (excluding new line). So something like:
\/cleaning\/(.+?logo\.png)$
should find all the images you want, then:
/logos/$1
should replace them as you wanted.
Demo: https://regex101.com/r/dmAjjv/1/
I need some help with RegEx, it may be a basic stuff but I cannot find a correct way how to do it. Please help!
So, here's my question:
I have a list of URLs, that are invalid because of double slash, like this:
http://website.com//wp-content/folder/file.jpg, to fix it I need to remove all double slashes except the first one followed by colon (http://), so fixed URL is this: http://website.com/wp-content/folder/file.jpg.
I need to do it with RegExp.
Variant 1
url.replace(/\/\//g,'/'); // => http:/website.com/wp-content/folder/file.jpg
will replace all double slashed (//), including the first one, which is not correct.
example here:
https://regex101.com/r/NhCVMz/2
You may use
url = url.replace(/(https?:\/\/)|(\/){2,}/g, "$1$2")
See the regex demo
Note: a ^ anchor at the beginning of the pattern might be used if the strings are entire URLs.
This pattern will match and capture http:// or https:// and will restore it in the resulting string with the $1 backreference and all other cases of 2 or more / will be matched by (\/){2,} and only 1 occurrence will be put back into the resulting string since the capturing group does not include the quantifier.
Find (^|[^:])/{2,}
Replace $1/
delimited: /(^|[^:])\/{2,}/