How to extract string between dash with regex in javascript? - javascript

I have a string in javascript:
const str = "bugfix/SOME-9234-add-company"; // output should be SOME-9234
const str2 = "SOME/SOME-933234-add-company"; // output should be SOME-933234
const str3 = "test/SOME-5559234-add-company"; // output should be SOME-5559234
and I want to extract the SOME-.. until the first - char.
I use this regex but didn't work. what is the correct regex?
const s = "bugfix/SOME-9234-add-company";
const r1 = s.match(/SOME-([1-9])/);
const r2 = s.match(/SOME-(.*)/);
const r3 = s.match(/SOME-(.*)-$/);
console.log({ r1, r2, r3 });

You could use the /(SOME-[\d]+)/g regex, e.g.
const strings = [
"bugfix/SOME-9234-add-company", // output should be SOME-9234
"SOME/SOME-933234-add-company", // output should be SOME-933234
"test/SOME-5559234-add-company" // output should be SOME-5559234
];
strings.forEach(string => {
const regex = /(SOME-[\d]+)/g;
const found = string.match(regex);
console.log(found[0]);
});

const s = "bugfix/SOME-9234-add-company";
// This one is close, but will return only on digit
console.log( s.match(/SOME-([1-9])/) );
// What you wanted:
console.log( s.match(/SOME-([1-9]+)/) ); // note the +, meaning '1 or more'
// these are also close.
// This'll give you everything after 'SOME':
console.log( s.match(/SOME-(.*)/) );
// This'll match if the last character of the line is a -
console.log( s.match(/SOME-(.*)-$/) );
//What you wanted:
console.log( s.match(/SOME-(.*?)-/) ); // Not end of line, but 'ungreedy'(the ?) which does 'untill the first - you encounter'
// instead of Using [1-9], you can also use \d, digits, for readability:
console.log( s.match(/SOME-(\d+)/) );

/(SOME-[^-]+)/ should work well. (capture everything what is not an hyphen after SOME-)
Or, if you know you have only digits, close to what you tried:
/(SOME-[1-9]+)/
You were missing a + to take more than one character.
I also changed the parenthesis to capture exactly what you show in the question (i.e., including the part with SOME)

If You don't want to use regex then this could be simple
const s = "bugfix/SOME-9234-add-company";
const str2 = "SOME/SOME-933234-add-company";
const str3 = "test/SOME-5559234-add-company";
const r1 = s.split("/")[1].split("-",2).join("-"); // "SOME-9234"
const r2 = str2.split("/")[1].split("-",2).join("-"); // "SOME-933234"
const r3 = str3.split("/")[1].split("-",2).join("-"); // "SOME-5559234"

In the patterns that you tried:
$ asserts the end of the string,
[1-9] matches a single digit 1-9 without the 0
.* will match any characters without a newline 0+ times
There is no need for capturing groups, you could match:
\bSOME-\d+
See a regex demo
Note that match will return an array, from which you could take the 0 index.
[
"bugfix/SOME-9234-add-company",
"SOME/SOME-933234-add-company",
"test/SOME-5559234-add-company"
].forEach(s => console.log(s.match(/\bSOME-\d+/)[0]));

Related

Calculating mixed numbers and chars and concatinating it back again in JS/jQuery

I need to manipulate drawing of a SVG, so I have attribute "d" values like this:
d = "M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985"
What I want is to "purify" all the values (to strip the chars from them), to calculate them (for the sake of simplicity, let's say to add 100 to each value), to deconstruct the string, calculate the values inside and then concatenate it all back together so the final result is something like this:
d = "M661.5402,368.917 C735.622,368.917 404.476,665.985 479.298,665.985"
Have in mind that:
some values can start with a character
values are delimited by comma
some values within comma delimiter can be delimited by space
values are decimal
This is my try:
let arr1 = d.split(',');
arr1 = arr1.map(element => {
let arr2 = element.split(' ');
if (arr2.length > 1) {
arr2 = arr2.map(el => {
let startsWithChar = el.match(/\D+/);
if (startsWithChar) {
el = el.replace(/\D/g,'');
}
el = parseFloat(el) + 100;
if (startsWithChar) {
el = startsWithChar[0] + el;
}
})
}
else {
let startsWithChar = element.match(/\D+/);
if (startsWithChar) {
element = element.replace(/\D/g,'');
}
element = parseFloat(element) + 100;
if (startsWithChar) {
element = startsWithChar[0] + element;
}
}
});
d = arr1.join(',');
I tried with regex replace(/\D/g,'') but then it strips the decimal dot from the value also, so I think my solution is full of holes.
Maybe another solution would be to somehow modify directly each of path values/commands, I'm opened to that solution also, but I don't know how.
const s = 'M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985'
console.log(s.replaceAll(/[\d.]+/g, m=>+m+100))
You might use a pattern to match the format in the string with 2 capture groups.
([ ,]?\b[A-Z]?)(\d+\.\d+)\b
The pattern matches:
( Capture group 1
[ ,]?\b[A-Z]? Match an optional space or comma, a word boundary and an optional uppercase char A-Z
) Close group 1
( Capture group 2
\d+\.\d+ Match 1+ digits, a dot and 1+ digits
) Close group 1
\b A word boundary to prevent a partial word match
Regex demo
First capture the optional delimiter followed by an optional uppercase char in group 1, and the decimal number in group 2.
Then add 100 to the decimal value and join back the 2 group values.
const d = "M561.5402,268.917 C635.622,268.917 304.476,565.985 379.298,565.985";
const regex = /([ ,]?\b[A-Z]?)(\d+\.\d+)\b/g;
const res = Array.from(
d.matchAll(regex), m => m[1] + (+m[2] + 100)
).join('');
console.log(res);

Is there a way to remove a newline character within a string in an array?

I am trying to parse an array using Javascript given a string that's hyphenated.
- foo
- bar
I have gotten very close to figuring it out. I have trimmed it down to where I get the two items using this code.
const chunks = input.split(/\ ?\-\ ?/);
chunks = chunks.slice(1);
This would trim the previous input down to this.
["foo\n", "bar"]
I've tried many solutions to get the newline character out of the string regardless of the number of items in the array, but nothing worked out. It would be greatly appreciated if someone could help me solve this issue.
You could for example split, remove all the empty entries, and then trim each item to also remove all the leading and trailing whitespace characters including the newlines.
Note that you don't have to escape the space and the hyphen.
const input = `- foo
- bar`;
const chunks = input.split(/ ?- ?/)
.filter(Boolean)
.map(s => s.trim());
console.log(chunks);
Or the same approach removing only the newlines:
const input = `- foo
- bar`;
const chunks = input.split(/ ?- ?/)
.filter(Boolean)
.map(s => s.replace(/\r?\n|\r/g, ''));
console.log(chunks);
Instead of split, you might also use a match with a capture group:
^ ?- ?(.*)
The pattern matches:
^ Start of string
?- ? Match - between optional spaces
(.*) Capture group 1, match the rest of the line
const input = `- foo
- bar`;
const chunks = Array.from(input.matchAll(/^ ?- ?(.*)/gm), m => m[1]);
console.log(chunks);
You could loop over like so and remove the newline chars.
const data = ["foo\n", "bar"]
const res = data.map(str => str.replaceAll('\n', ''))
console.log(res)
Instead of trimming after the split. Split wisely and then map to replace unwanted string. No need to loop multiple times.
const str = ` - foo
- bar`;
let chunks = str.split("\n").map(s => s.replace(/^\W+/, ""));
console.log(chunks)
let chunks2 = str.split("\n").map(s => s.split(" ")[2]);
console.log(chunks2)
You could use regex match with:
Match prefix "- " but exclude from capture (?<=- ) and any number of character different of "\n" [^\n]*.
const str = `
- foo
- bar
`
console.log(str.match(/(?<=- )[^\n]*/g))
chunks.map((data) => {
data = data.replace(/(\r\n|\n|\r|\\n|\\r)/gm, "");
return data;
})
const str = ` - foo
- bar`;
const result = str.replace(/([\r\n|\n|\r])/gm, "")
console.log(result)
That should remove all kinds of line break in a string and after that you can perform other actions to get the expected result like.
const str = ` - foo
- bar`;
const result = str.replace(/([\r\n|\n|\r|^\s+])/gm, "")
console.log(result)
const actualResult = result.split('-')
actualResult.splice(0,1)
console.log(actualResult)

Match any lowercase/uppercase chained character and add an additional one

In Javascript, I would like to do the following.
When I match a lowerCase followed by a upperCase, I would like to add a special character in beetween it.
ex :
myHouse => my_House
aRandomString => a_Random_String
etc...
I made a regex for this match =>
/([a-z][A-Z](.{0}))+/g
the problem I have is if I do
"aRandomString".replace(/([a-z][A-Z](.{0}))+/g, '_')
it will of course do => _ando_tring
EDIT :
I made this but, isn't this overly complicated ?
var mString = "aRandomString";
var match = mString.match(/([a-z][A-Z](.{0}))+/g, '_')
var save = [...match]
match = match.map(e => [e.slice(0, 1), '_', e.slice(1)].join(''))
save.forEach((s,i) => mString = mString.replace(s, match[i]))
console.log(mString)
Yes. You can easily match just the lowercase, uppercase pattern you are looking for and replace with a replacer.
const mString = "aTestStringForMULTIPLEUpperCase";
const uString = mString.replace(/[a-z][A-Z]/g, v => `${v[0]}_${v[1]}`);
console.log(uString);
A more robust/generic approach, which takes an additional uppercase boundary into account (not only lower followed by upper but also an upper in between another left side upper and right side lower) might look like that ...
const regXUppecaseBoundaries = (/(?:(?<=[a-z])[A-Z])|(?:(?<=[A-Z])[A-Z](?=[a-z]))/g);
const sampleText = `myHouse aRandomString
aRandomString aTestStringForMULTIPLEUpperCase
myHouse AaAAaTestStringForMULTIPLEUpperCase`;
// also check ... [https://regex101.com/r/OpmSbx/1]
console.log(
sampleText.replace(regXUppecaseBoundaries, '_$&')
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Get Initials of full names with accented characters through REGEX

I want to get the initials of a full name even if the name has accents or dots or comma.
If I have the name:
"Raúl, Moreno. Rodríguez Carlos"
I get "RLMRGC".
my code is:
user.displayName.match(/\b[a-zA-Z]/gm).join('').toUpperCase()
I want to get "RMRC". Thanks in advance.
My guess is that this expression might work:
const regex = /[^A-Z]/gm;
const str = `Raúl, Moreno. Rodríguez Carlos`;
const subst = ``;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log(result);
Try this (with REGEX):
const data = "Raúl, Moreno. Rodríguez Carlos";
const result = data.match(/\b[A-Z]/gm);
console.log(result);
other solution without REGEX:
const data = "Ędward Ącki";
const result = [...data].filter((c, k, arr) => c !== ' ' && (k == 0 || arr[k-1] == ' ' ))
console.log(result);
A fully Unicode compatible solution should match any letter after a char other than letter or digit.
Here are two solutions: 1) an XRegExp based solution for any browser, and 2) an ECMAScript 2018 only JS environment compatible solution.
var regex = XRegExp("(?:^|[^\\pL\\pN])(\\pL)");
console.log( XRegExp.match("Łukasz Żak", regex, "all").map(function(x) {return x.charAt(x.length - 1);}).join('').toUpperCase() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>
ECMAScript 2018 compliant solution:
// ONLY WORKING IN ECMAScript2018 COMPLIANT JS ENVIRONMENT!
var regex = /(?<![\p{N}\p{L}])\p{L}/gu;
console.log( "Łukasz Żak".match(regex).join('').toUpperCase() );
// => ŁŻ
NOTE:
(?:^|[^\pL\\pN])(\pL) matches start of a string and any char but letter and digit and then matches any letter (since the char matched by the first non-capturing group is not necessary, .map(function(x) {return x.charAt(x.length - 1);}) is required to get the last char of the match)
(?<![\p{N}\p{L}])\p{L} matches any letter (\p{L}) that is not preceded with a digit or letter (see the negative lookbehind (?<![\p{N}\p{L}]))

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)

Categories

Resources