Regular expression to match environment - javascript

I'm using JavaScript and I'm looking for a regex to match the placeholder "environment", which will be a different value like "production" or "development" in "real" strings.
The regex should match "environment" in both strings:
https://company-application-environment.company.local
https://application-environment.company.local
I have tried:
[^-]+$ which matches environment.company.local
\.[^-]+$ which matches .company.local
How do I get environment?

You may use this regex based on a positive lookahead:
/[^.-]+(?=\.[^-]+$)/
Details:
[^.-]+: Match 1+ of any char that is not - and .
(?=\.[^-]+$): Lookahead to assert that we have a dot and 1+ of non-hyphen characters till end.
RegEx Demo
Code:
const urls = [
"https://company-application-environment.company.local",
"https://application-environment.company.local",
"https://application-production.any.thing",
"https://foo-bar-baz-development.any.thing"
]
const regex = /[^.-]+(?=\.[^-]+$)/;
urls.forEach(url =>
console.log(url.match(regex)[0])
)

Not the fanciest reg exp, but gets the job done.
const urls = [
"https://company-application-environment.company.local",
"https://application-environment.company.local",
"https://a-b-c-d-e-f.foo.bar"
]
urls.forEach(url =>
console.log(url.match(/-([^-.]+)\./)[1])
)

As an alternative you might use URL, split on - and get the last item from the array. Then split on a dot and get the first item.
[
"https://company-application-environment.company.local",
"https://application-environment.company.local"
].forEach(s => {
let env = new URL(s).host.split('-').pop().split('.')[0];
console.log(env);
})

Match for known environments
var tests = [
'https://company-application-development.company.local',
'https://application-production.company.local',
'https://appdev.company.local',
'https://appprod.company.local'
];
tests.forEach(test => {
var pattern = /(development|dev|production|prod)/g;
var match = test.match(pattern);
console.log(`environment = ${match}`);
});
In this case, the best way to match is to literally use the word you are looking for.
And if you need to match multiple values in the environment position, use the RegEx or format. See the MDN.
(production|development)

Related

Check for pattern match with UUIDv4 in JavaScript

I am looking for a pattern match with certain string before and after the uuid.
e.g.user/a24a6ea4-ce75-4665-a070-57453082c256/photo/a24a6ea4-ce75-4665-a070-57453082c256
const regexExp = new RegExp(/^user\/[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i);
console.log(regexExp.test("user/a24a6ea4-ce75-4665-a070-57453082c256")); // true
console.log(regexExp.test("user/a24a6ea4-ce75-4665-a070-57453082c256/photo")); // false
What I am expecting is to match user/{uuid}/* How to use a wildcard after the uuid?
If you want to match both, you can omit using the RegExp constructor as you are already using a literal and optionally match / followed by the rest of the string.
The [4] can be just 4
const regexExp = /^user\/[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}(?:\/.*)?$/i;
See the regex101 demo.
const regexExp = /^user\/[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}(?:\/.*)?$/i;
[
"user/a24a6ea4-ce75-4665-a070-57453082c256",
"user/a24a6ea4-ce75-4665-a070-57453082c256/photo",
"user/a24a6ea4-ce75-4665-a070-57453082c256asdasd"
].forEach(s =>
console.log(`${s} --> ${regexExp.test(s)}`)
);

URL regular expression pattern

I would like to parse URLs with Regular Expressions and find a pattern that matches with https://*.global.
Here is my URL test string on regex101.
Ideally, the regex would return https://app8.global instead of cover other https string.
const URL = `https://temp/"https://app8.global"https://utility.localhost/`;
const regex = /https:\/\/(.+?)\.global(\/|'|"|`)/gm;
const found = URL.match(regex);
console.log(found);
How would I manipulate the regex so it will return the https://*.global?
First of all, you need to exclude slashes from the starting part, otherwise it'll match things from the previous url:
const regex = /https:\/\/([^\/]+?)\.global(\/|'|"|`)/gm;
Now, you can convert the weird 4 character or with a character group:
const regex = /https:\/\/([^\/]+?)\.global[\/'"`]/gm;
And now you can get the matches and trim off that last character:
const matches = URL.match(regex).map(v => v.slice(0, -1));
Then, matches would evaluate to ["https://app8.global"].
Using Group RegExp.$1
const URL = `https://temp/"https://app8.global"https://utility.localhost/`;
const regex = /(https:\/\/([^\/]+?)\.global[\/'"`])/;
const found = URL.match(regex);
console.log(RegExp.$1);

regex exclude matches that don't meet one of two patterns separated by delimiter

In Javascript using string.match():
I have a string like: foo_2:asc,foo2:desc,foo3,foo4:wrong
the matches should look like ["foo_2:asc", "foo2:desc", "foo3"]
but instead the best I can get it to so far is a match returning ["foo_2:asc", "foo2:desc", "foo3", "wrong"]
the regex that I'm using currently for the above wrong match is: /([a-z0-9_]+?[:asc|:desc]*?)(?=,|$)/gi
I also need a regex that will return the opposite, i.e. find a match for all patterns between the delimiter that doesn't match the pattern rules of thing_1:asc, thing_1:desc, or thing_1 i.e. this would be used to validate the string, while the other would be used to gather the values (i.e. instead of splitting the string manually). So the result of the original would be ["foo4:wrong"] as the part of that string that doesn't meet the pattern.
Assuming that the only valid forms are words followed by one of :asc, :desc or nothing, you can do what you want by splitting the string, first on , and then on : and checking whether there are two values as a result of the last split and the second is not one of asc or desc:
const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';
const errs = str.split(',').filter(v => v.split(':').length == 2 && ['asc', 'desc'].indexOf(v.split(':')[1]) == -1);
console.log(errs);
If you must use regex, you can split on , and then filter based on the value not matching ^\w+(:(asc|desc))$:
const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';
const errs = str.split(',').filter(v => !v.match(/^\w+(:(?:asc|desc))?$/));
console.log(errs);
If the format of the string is guaranteed to be \w+(:\w+)?(,\w+(:\w+)?)* you can simplify to this:
const str = 'foo_2:asc,foo2:desc,foo3,foo4:wrong';
const errs = str.match(/\w+:(?!(?:asc|desc)\b)\w+/g);
console.log(errs);
If you'd like regex for this purpose, you probably can just add start from coma or string start.
/(^|\,)([a-z0-9_]+?(:asc|:desc)*?)(?=,|$)/gi
also pay attention [:asc|:desc] changed to (:asc|:desc), to avoid false positive cases like:
foo5:aaa,foo6:d,foo7:,foo8|,et:c
it just matches by any char in square brackets.
Regarding opposite, try something like:
/(^|\,)(?!([a-z0-9_]+?(:asc|:desc)*?)(?=,|$))[^,$]+/gi
seems to do the job.
For the match I came up with
/(?<=(^|,))((\w+(?!:)|\w+(:asc|:desc)))(?=($|,))/g
Example: https://regex101.com/r/QLJeDV/3/
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".match(/(?<=(^|,))((\w+(?!:)|\w+(:asc|:desc)))(?=($|,))/g)
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]
Or even
/(?<=(^|,))\w+(:asc|:desc)?(?=($|,))/g
should work. Example: https://regex101.com/r/QLJeDV/6/
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".match(/(?<=(^|,))\w+(:asc|:desc)?(?=($|,))/g)
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]
They are using lookahead and lookbehind.
For the "opposite", I don't know how to match something and then "negate" a later pattern, but only know how to negate the result of whether it is a complete match, so I had to split it. The "opposite":
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => !/^((\w+(?!:)|\w+(:asc|:desc)))$/.test(s))
[ 'foo4:wrong' ]
and the "original":
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => /^((\w+(?!:)|\w+(:asc|:desc)))$/.test(s))
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]
Or it can be simplified as:
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => !/^\w+(:asc|:desc)?$/.test(s))
[ 'foo4:wrong' ]
> "foo_2:asc,foo2:desc,foo3,foo4:wrong".split(",").filter(s => /^\w+(:asc|:desc)?$/.test(s))
[ 'foo_2:asc', 'foo2:desc', 'foo3' ]

Manipulate a string containing a file's path to get only the file name

I got a file path as
falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV
as file extension will change as file type
file path will also change
how could I manipulate string to get file name as
BD6FE729-70F1-48B0-83EB-8E7D956E599E"
is in given example
2nd example of path and file type change
falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540ppphrx%252Fiia-mas-app-new//IIAMASATTCHMENTS/DD6FE729-60F2-58B0-8M8B-8E759R6E547K.jpeg
you can do simply
let str="falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV"
console.log( str.split(".")[0].split("/").pop()
)
just remember split split pop
Some variation of slice/split would work
const str = 'falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV'
console.log(
str.slice(str.lastIndexOf("/")+1).split(".")[0]
)
// or
console.log(
str.split("/").pop().split(".")[0]
)
You can use regular expression for example.
The first thing comes in my mind is:
const filepath = 'falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV'
const filenameWithoutExtension = filepath.match(/IIAMASATTCHMENTS\/(.*)\./)[1] // "BD6FE729-70F1-48B0-83EB-8E7D956E599E"
console.log(filenameWithoutExtension)
If you know the format of the value you want to capture, you might get a more exact match using a regex and capture your value in the first capturing group.
You might use the /i flag to make the match case insensitive.
([A-Z0-9]+(?:-[A-Z0-9]+){4})\.\w+$
That will match:
( Capturing group
[A-Z0-9]+ Match 1+ times what is listed in the character class
(?:-[A-Z0-9]+){4} Repeat 4 times matching a hyphen and 1+ times what is listed in the character class
) Close capturing group
\.\w+$ Match a dot, 1+ times a word char and assert the end of the string
Regex demo
let strs = [
`falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV`,
`falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540ppphrx%252Fiia-mas-app-new//IIAMASATTCHMENTS/DD6FE729-60F2-58B0-8M8B-8E759R6E547K.jpeg`
];
let pattern = /([A-Z0-9]+(?:-[A-Z0-9]+){4})\.\w+$/i;
strs.forEach(str => console.log(str.match(pattern)[1]));
You could use regular expressions like here:
function get_filename(str) {
const regex = /\/([A-Z0-9\-_]+)\.[\w\d]+/gm;
let m = regex.exec(str);
return m[1];
}
console.log(
get_filename(`falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540ppphrx%252Fiia-mas-app-new//IIAMASATTCHMENTS/DD6FE729-60F2-58B0-8M8B-8E759R6E547K.jpeg`)
)
var filpath = "falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV"
console.log(
filpath.substring(filpath.lastIndexOf('/') + 1, filpath.length).substring(1, filpath.substring(filpath.lastIndexOf('/') + 1, filpath.length).lastIndexOf('.'))
)
var str = "falsefile:///var/mobile/Containers/Data/Application/D4B6F6CD-5E5C-4459-90CC-0C649B3B31B8/Documents/ExponentExperienceData/%2540hherax%252Fiia-mas-app-new//IIAMASATTCHMENTS/BD6FE729-70F1-48B0-83EB-8E7D956E599E.MOV",
re = /[\w|-]*\.\w*/
stringNameWithExt = str.match(re)
stringNameWithoutExt = str.match(re)[0].split(".")[0]
console.log(stringNameWithoutExt)

Extract word between '=' and '('

I have the following string
234234=AWORDHERE('sdf.'aa')
where I need to extract AWORDHERE.
Sometimes there can be space in between.
234234= AWORDHERE('sdf.'aa')
Can I do this with a regular expression?
Or should I do it manually by finding indexes?
The datasets are huge, so it's important to do it as fast as possible.
Try this regex:
\d+=\s?(\w+)\(
Check Demo
in Javascript it would like that:
var myString = "234234=AWORDHERE('sdf.'aa')";// or 234234= AWORDHERE('sdf.'aa')
var myRegexp = /\d+=\s?(\w+)\(/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // AWORDHERE
You could do this at least three ways. You need to benchmark to see what's fastest.
Substring w/ indexes
function extract(from) {
var ixEq = from.indexOf("=");
var ixParen = from.indexOf("(");
return from.substring(ixEq + 1, ixParen);
}
.
Splits
function extract(from) {
var spEq = from.split("=");
var spParen = spEq[1].split("(");
return spParen[0];
}
Regex (demo)
Here is some sample regex you could use
/[^=]+=([^(]+).*/g
This says
[^=]+ - One or more character which is not an =
= - The = itself
( - creates a matching group so you can access your match in code
[^(]+ - One or more character which is not a (
) - closes the matching group
.* - Matches the rest of the line
the /g on the end tells it to perform the match on all lines.
Using look around you can search for string preceded by = and followed by ( as following.
Regex: (?<==)[A-Z ]+(?=\()
Explanation:
(?<==) checks if [A-Z ] is preceded by an =.
[A-Z ]+ matches your pattern.
(?=\() checks if matched pattern is followed by a (.
Regex101 Demo
var str = "234234= AWORDHERE('sdf.'aa')";
var regexp = /.*=\s+(\w+)\(.*\)/g;
var match = regexp.exec(str);
alert( match[1] );
I made my solution for this just a little more general than you asked for, but I don't think it takes much more time to execute. I didn't measure. If you need greater efficiency than this provides, comment and I or someone else can help you with that.
Here's what I did, using the command prompt of node:
> var s = "234234= AWORDHERE('sdf.'aa')"
undefined
> var a = s.match(/(\w+)=\s*(\w+)\s*\(.*/)
undefined
> a
[ '234234= AWORDHERE(\'sdf.\'aa\')',
'234234',
'AWORDHERE',
index: 0,
input: '234234= AWORDHERE(\'sdf.\'aa\')' ]
>
As you can see, this matches the number before the = in a[1], and it matches the AWORDHERE name as you requested in a[2]. This will work with any number (including zero) spaces before and/or after the =.

Categories

Resources