Javascript (node) regex doesn't seem to match start of string - javascript

im struggling with regular expressions in Javascript, they don't seem to start at the beginning of the string. In a simple example bellow I want to get the file name and then everything after the first colon
//string
file.text:16: lots of random text here with goes on for ages
//regex
(.?)[:](.*)
// group 1 returns 't'

/^([^:]+):(.*)/.exec('file.text:16: lots of random text here with goes on for ages')
gives ....
["file.text:16: lots of random text here with goes on for ages", "file.text", "16: lots of random text here with goes on for ages"]

Try this regex:
/^([^:]+)[:](.*)/
Explaination:
^ #Start of string
( #Start of capturing class #1
[^:] #Any character other than :
+ #One or more of the previous character class
) #End of capturing class #1
[:] #One :
(.*) #Any number of characters other than newline
The ? operator captures zero or one of the previous symbol only.
You could also use string operations instead:
str = "file.text:16:";
var n = str.indexOf(":");
var fileName = str.substr(0, n);
var everythingElse = str.substr(n);

The ? operator returns 0 or 1 matches. You want the * operator, and you should select everything that isn't a : in the first set
([^:]*)[:](.*)

Non-regexy answer:
var a = s.split(":");
Then join a[1] and remaining elements.
Or just get the index of the first semicolon and create two strings using that.

Related

regex: replace dynamically a searched word

I want to replace file:///Downloads/project by a another word like a github link :
const string = 'file:///Downloads/project/users/controllers/users/controller.js';
I tried working with .replace a world by a world but i got in the problem that file:///Downloads/projectis a dynamic value that may change from time to time.
string.replace(/file\:\/\/Downloads\/project\/users\/controller.js/gi, 'https://gitlab.com')
So i want to search for the word project and replace from it backward by another path or word
To achieve expected result, use below option of using indexOf and substr and finally replacing with gitlab url
Get index of project
Get string from 0 to index of project
Replace string from step 2 with gitlab using replace option
const string = 'file:///Downloads/project/users/controllers/users/controller.js';
const index = string.indexOf('project')
console.log(string.replace(string.substr(0, index), 'https://gitlab.com/'))
codepen - https://codepen.io/nagasai/pen/qvjdEa?editors=1010
Using regex you can match the first group which includes /project and replace the first parenthesized capture group with your https://gitlab.com. Here p1 denotes first parenthesized capture group and p2 denotes second parenthesized capture group.
const str = 'file:///Downloads/project/users/controllers/users/controller.js';
const res = str.replace(/^(.|\/)+\w*project(.+)*/gi, function(match, p1, p2) {
return 'https://gitlab.com' + p2;
});
console.log(res);
you don't need a regex for that
const string = 'file:///Downloads/project/users/controllers/users/controller.js',
yourValue = "file:///Downloads/project/",
res = string.replace(yourValue, "https://gitlab.com/")
console.log(res)
'https://gitlab.com/' + string.substr(string.indexOf('project'))
First find the position of 'project' in your string
string.indexOf('project')
then get a substring from that position to the end of the string (substr goes till the end when no second arg is provided)
string.substring(indexOfProject)
then concat it with '+'. Note that the url ends with '/' because your string will begin with 'p'.
'https://gitlab.com/' + extractedString

Javascript regex between string delimiters

I have the following string:
%||1234567890||Joe||% some text winter is coming %||1234567890||Robert||%
PROBLEM: I am trying to match all occurrences between %||....||% and process those substring matches
MY REGEX: /%([\s\S]*?)(?=%)/g
MY CODE
var a = "%||1234567890||Joe||% some text winter is coming %||1234567890||Robert||%";
var pattern = /%([\s\S]*?)(?=%)/g;
a.replace( pattern, function replacer(match){
return match.doSomething();
} );
Now the patterns seems to be selecting the everything between the first and last occurrence of %|| .... %||
MY
FIDDLE
WHAT I NEED:
I want to iterate over the matches
%||1234567890||Joe||%
AND
%||1234567890||Robert||%
and do something
You need to use a callback inside a String#replace and modify the pattern to only match what is inside %|| and ||% like this:
var a = "%||1234567890||Joe||% some text winter is coming %||1234567890||Robert||%";
var pattern = /%\|\|([\s\S]*?)\|\|%/g;
a = a.replace( pattern, function (match, group1){
var chunks = group1.split('||');
return "{1}" + chunks.join("-") + "{/1}";
} );
console.log(a);
The /%\|\|([\s\S]*?)\|\|%/g pattern will match:
%\|\| - a %|| substring
([\s\S]*?) - Capturing group 1 matching any 0+ chars as few as possible up to the first...
\|\|% - a ||% substring
/g - multiple times.
Because he tries to take as much as possible, and [\s\S] basically means "anything". So he takes anything.
RegExp parts without escaping, exploded for readability
start tag : %||
first info: ([^|]*) // will stop at the first |
separator : ||
last info : ([^|]*) // will stop at the first |
end tag : ||%
Escaped RegExp:
/%\|\|([^\|]*)\|\|([^\|]*)\|\|%/g

Test if a sentence is matching a text declaration using regex

I want to test if a sentence like type var1,var2,var3 is matching a text declaration or not.
So, I used the following code :
var text = "int a1,a2,a3",
reg = /int ((([a-z_A-Z]+[0-9]*),)+)$/g;
if (reg.test(text)) console.log(true);
else console.log(false)
The problem is that this regular expression returns false on text that is supposed to be true.
Could someone help me find a good regular expression matching expressions as in the example above?
You have a couple of mistekes.
As you wrote, the last coma is required at the end of the line.
I suppose you also want to match int abc123 as correct string, so you need to include letter to other characters
Avoid using capturing groups for just testing strings.
const str = 'int a1,a2,a3';
const regex = /int (?:[a-zA-Z_](?:[a-zA-Z0-9_])*(?:\,|$))+/g
console.log(regex.test(str));
You will need to add ? after the comma ,.
This token ? matches between zero and one.
Notice that the last number in your text a3 does not have , afterward.
int ((([a-z_A-Z]+[0-9]*),?)+)$

javascript replace text at second occurence of "/"

I have this string
"/mp3/mysong.mp3"
I need to do make this string look like this with javascript.
"/mp3/myusername/mysong.mp3"
My guess would be to find second occurrence of "/", then append "myusername/" there or prepend "/myusername" but I'm not sure how to do this in javascript.
Just capture the characters upto the second / symbol and store it into a group. Then replace the matched characters with the characters inside group 1 plus the string /myusername
Regex:
^(\/[^\/]*)
Replacement string:
$1/myusername
DEMO
> var r = "/mp3/mysong.mp3"
undefined
> r.replace(/^(\/[^\/]*)/, "$1/myusername")
'/mp3/myusername/mysong.mp3'
OR
Use a lookahead.
> r.replace(/(?=\/[^/]*$)/, "/myusername")
'/mp3/myusername/mysong.mp3'
This (?=\/[^/]*$) matches a boundary which was just before to the last / symbol. Replacing the matched boundary with /myusername will give you the desired result.
This works -
> "/mp3/mysong.mp3".replace(/(.*?\/)(\w+\.\w+)/, "$1myusername\/$2")
"/mp3/myusername/mysong.mp3"
Demo and explanation of the regex here
use this :
var str = "/mp3/mysong.mp3";
var res = str.replace(/(.*?\/){2}/g, "$1myusername/");
console.log(res);
this will insert the text myusername after the 2nd / .

getting contents of string between digits

have a regex problem :(
what i would like to do is to find out the contents between two or more numbers.
var string = "90+*-+80-+/*70"
im trying to edit the symbols in between so it only shows up the last symbol and not the ones before it. so trying to get the above variable to be turned into 90+80*70. although this is just an example i have no idea how to do this. the length of the numbers, how many "sets" of numbers and the length of the symbols in between could be anything.
many thanks,
Steve,
The trick is in matching '90+-+' and '80-+/' seperately, and selecting only the number and the last constant.
The expression for finding the a number followed by 1 or more non-numbers would be
\d+[^\d]+
To select the number and the last non-number, add parens:
(\d+)[^\d]*([^\d])
Finally add a /g to repeat the procedure for each match, and replace it with the 2 matched groups for each match:
js> '90+*-+80-+/*70'.replace(/(\d+)[^\d]*([^\d])/g, '$1$2');
90+80*70
js>
Or you can use lookahead assertion and simply remove all non-numerical characters which are not last: "90+*-+80-+/*70".replace(/[^0-9]+(?=[^0-9])/g,'');
You can use a regular expression to match the non-digits and a callback function to process the match and decide what to replace:
var test = "90+*-+80-+/*70";
var out = test.replace(/[^\d]+/g, function(str) {
return(str.substr(-1));
})
alert(out);
See it work here: http://jsfiddle.net/jfriend00/Tncya/
This works by using a regular expression to match sequences of non-digits and then replacing that sequence of non-digits with the last character in the matched sequence.
i would use this tutorial, first, then review this for javascript-specific regex questions.
This should do it -
var string = "90+*-+80-+/*70"
var result = '';
var arr = string.split(/(\d+)/)
for (i = 0; i < arr.length; i++) {
if (!isNaN(arr[i])) result = result + arr[i];
else result = result + arr[i].slice(arr[i].length - 1, arr[i].length);
}
alert(result);
Working demo - http://jsfiddle.net/ipr101/SA2pR/
Similar to #Arnout Engelen
var string = "90+*-+80-+/*70";
string = string.replace(/(\d+)[^\d]*([^\d])(?=\d+)/g, '$1$2');
This was my first thinking of how the RegEx should perform, it also looks ahead to make sure the non-digit pattern is followed by another digit, which is what the question asked for (between two numbers)
Similar to #jfriend00
var string = "90+*-+80-+/*70";
string = string.replace( /(\d+?)([^\d]+?)(?=\d+)/g
, function(){
return arguments[1] + arguments[2].substr(-1);
});
Instead of only matching on non-digits, it matches on non-digits between two numbers, which is what the question asked
Why would this be any better?
If your equation was embedded in a paragraph or string of text. Like:
This is a test where I want to clean up something like 90+*-+80-+/*70 and don't want to scrap the whole paragraph.
Result (Expected) :
This is a test where I want to clean up something like 90+80*70 and don't want to scrap the whole paragraph.
Why would this not be any better?
There is more pattern matching, which makes it theoretically slower (negligible)
It would fail if your paragraph had embedded numbers. Like:
This is a paragraph where Sally bought 4 eggs from the supermarket, but only 3 of them made it back in one piece.
Result (Unexpected):
This is a paragraph where Sally bought 4 3 of them made it back in one piece.

Categories

Resources