Comparison of back references in javascript regex - javascript

var x = "SomeText http://g.com";
var y = x.replace(/<a href="([^"]+)">([^<]+)<\/a>/igm, ('$2' == '$1')?"t":"f");
The comparison is returning false. And y is now "SomeText f".
How do I compare and get "SomeText t" ? Am I missing something in the condition ?
Printing both the back references prints the same string.
var y = x.replace(/<a href="([^"]+)">([^<]+)<\/a>/igm, '($2)($1)')
This prints the same url for both back references.

The only time that JS will do anything special with a string like $1 or $2 is if it is part of the resulting string passed as the second argument to .replace().
What you have as '$2' === '$1' was saying if the string "$2" is the same as the string "$1", which is clearly always false.
Instead, what you can do is use the .match() method to get the various backreferences as an array which you can index into.
Try the following:
var x = "SomeText http://g.com";
var regex = /<a href="([^"]+)">([^<]+)<\/a>/igm;
var matches = x.match(regex);
var y = x.replace(regex, matches[2] == matches[1]?"t":"f");

Related

How to get the string value after the colon?

I really need your help,
How can I check a string to see if it has a ":" and then if it does, to get the string value after the ":"
ie.
var x = "1. Search - File Number: XAL-2017-463288"
var y = "XAL-2017-463288"
//check for the colon
if (x.indexOf(':') !== -1) {
//split and get
var y = x.split(':')[1];
}
Split on the colon, and grab the second member of the result. This assumes you want the first colon found.
var y = x.split(":")[1];
If the string didn't have a :, then y will be undefined, so a separate check isn't needed.
Or you could use .indexOf(). This assumes there's definitely a colon. Otherwise you'll get the whole string.
var y = x.slice(x.indexOf(":") + 1);
If you wanted to check for the colon, then save the result of .indexOf() to a variable first, and only do the .slice() if the index was not -1.

regex to find specific strings in javascript

disclaimer - absolutely new to regexes....
I have a string like this:
subject=something||x-access-token=something
For this I need to extract two values. Subject and x-access-token.
As a starting point, I wanted to collect two strings: subject= and x-access-token=. For this here is what I did:
/[a-z,-]+=/g.exec(mystring)
It returns only one element subject=. I expected both of them. Where i am doing wrong?
The g modifier does not affect exec, because exec only returns the first match by specification. What you want is the match method:
mystring.match(/[a-z,-]+=/g)
No regex necessary. Write a tiny parser, it's easy.
function parseValues(str) {
var result = {};
str.split("||").forEach(function (item) {
var parts = item.split("=");
result[ parts[0] /* key */ ] = parts[1]; /* value */
});
return result;
}
usage
var obj = parseValues("subject=something||x-access-token=something-else");
// -> {subject: "something", x-access-token: "something-else"}
var subj = obj.subject;
// -> "something"
var token = obj["x-access-token"];
// -> "something-else"
Additional complications my arise when there is an escaping schema involved that allows you to have || inside a value, or when a value can contain an =.
You will hit these complications with regex approach as well, but with a parser-based approach they will be much easier to solve.
You have to execute exec twice to get 2 extracted strings.
According to MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
If your regular expression uses the "g" flag, you can use the exec() method multiple times to find successive matches in the same string.
Usually, people extract all strings matching the pattern one by one with a while loop. Please execute following code in browser console to see how it works.
var regex = /[a-z,-]+=/g;
var string = "subject=something||x-access-token=something";
while(matched = regex.exec(string)) console.log(matched);
You can convert the string into a valid JSON string, then parse it to retrieve an object containing the expected data.
var str = 'subject=something||x-access-token=something';
var obj = JSON.parse('{"' + str.replace(/=/g, '":"').replace(/\|\|/g, '","') + '"}');
console.log(obj);
I don't think you need regexp here, just use the javascript builtin function "split".
var s = "subject=something1||x-access-token=something2";
var r = s.split('||'); // r now is an array: ["subject=something1", "x-access-token=something2"]
var i;
for(i=0; i<r.length; i++){
// for each array's item, split again
r[i] = r[i].split('=');
}
At the end you have a matrix like the following:
y x 0 1
0 subject something1
1 x-access-token something2
And you can access the elements using x and y:
"subject" == r[0][0]
"x-access-token" == r[1][0]
"something2" == r[1][1]
If you really want to do it with a pure regexp:
var input = 'subject=something1||x-access-token=something2'
var m = /subject=(.*)\|\|x-access-token=(.*)/.exec(input)
var subject = m[1]
var xAccessToken = m[2]
console.log(subject);
console.log(xAccessToken);
However, it would probably be cleaner to split it instead:
console.log('subject=something||x-access-token=something'
.split(/\|\|/)
.map(function(a) {
a = a.split(/=/);
return { key: a[0], val: a[1] }
}));

How can I split this string in JavaScript?

I have strings like this:
ab
rx'
wq''
pok'''
oyu,
mi,,,,
Basically, I want to split the string into two parts. The first part should have the alphabetical characters intact, the second part should have the non-alphabetical characters.
The alphabetical part is guaranteed to be 2-3 lowercase characters between a and z; the non-alphabetical part can be any length, and is gauranteed to only be the characters , or ', but not both in the one string (e.g. eex,', will never occur).
So the result should be:
[ab][]
[rx][']
[wq]['']
[pok][''']
[oyu][,]
[mi][,,,,]
How can I do this? I'm guessing a regular expression but I'm not particularly adept at coming up with them.
Regular expressions have is a nice special called "word boundary" (\b). You can use it, well, to detect the boundary of a word, which is a sequence of alpha-numerical characters.
So all you have to do is
foo.split(/\b/)
For example,
"pok'''".split(/\b/) // ["pok", "'''"]
If you can 100% guarantee that:
Letter-strings are 2 or 3 characters
There are always one or more primes/commas
There is never any empty space before, after or in-between the letters and the marks
(aside from line-break)
You can use:
/^([a-zA-Z]{2,3})('+|,+)$/gm
var arr = /^([a-zA-Z]{2,3})('+|,+)$/gm.exec("pok'''");
arr === ["pok'''", "pok", "'''"];
var arr = /^([a-zA-Z]{2,3})('+|,+)$/gm.exec("baf,,,");
arr === ["baf,,,", "baf", ",,,"];
Of course, save yourself some sanity, and save that RegEx as a var.
And as a warning, if you haven't dealt with RegEx like this:
If a match isn't found -- if you try to match foo','' by mixing marks, or you have 0-1 or 4+ letters, or 0 marks... ...then instead of getting an array back, you'll get null.
So you can do this:
var reg = /^([a-zA-Z]{2,3})('+|,+)$/gm,
string = "foobar'',,''",
result_array = reg.exec(string) || [string];
In this case, the result of the exec is null; by putting the || (or) there, we can return an array that has the original string in it, as index-0.
Why?
Because the result of a successful exec will have 3 slots; [*string*, *letters*, *marks*].
You might be tempted to just read the letters like result_array[1].
But if the match failed and result_array === null, then JavaScript will scream at you for trying null[1].
So returning the array at the end of a failed exec will allow you to get result_array[1] === undefined (ie: there was no match to the pattern, so there are no letters in index-1), rather than a JS error.
You could try something like that:
function splitString(string){
var match1 = null;
var match2 = null;
var stringArray = new Array();
match1 = string.indexOf(',');
match2 = string.indexOf('`');
if(match1 != 0){
stringArray = [string.slice(0,match1-1),string.slice(match1,string.length-1];
}
else if(match2 != 0){
stringArray = [string.slice(0,match2-1),string.slice(match2,string.length-1];
}
else{
stringArray = [string];
}
}
var str = "mi,,,,";
var idx = str.search(/\W/);
if(idx) {
var list = [str.slice(0, idx), str.slice(idx)]
}
You'll have the parts in list[0] and list[1].
P.S. There might be some better ways than this.
yourStr.match(/(\w{2,3})([,']*)/)
if (match = string.match(/^([a-z]{2,3})(,+?$|'+?$)/)) {
match = match.slice(1);
}

Javascript split only once and ignore the rest

I am parsing some key value pairs that are separated by colons. The problem I am having is that in the value section there are colons that I want to ignore but the split function is picking them up anyway.
sample:
Name: my name
description: this string is not escaped: i hate these colons
date: a date
On the individual lines I tried this line.split(/:/, 1) but it only matched the value part of the data. Next I tried line.split(/:/, 2) but that gave me ['description', 'this string is not escaped'] and I need the whole string.
Thanks for the help!
a = line.split(/:/);
key = a.shift();
val = a.join(':');
Use the greedy operator (?) to only split the first instance.
line.split(/: (.+)?/, 2);
If you prefer an alternative to regexp consider this:
var split = line.split(':');
var key = split[0];
var val = split.slice(1).join(":");
Reference: split, slice, join.
Slightly more elegant:
a = line.match(/(.*?):(.*)/);
key = a[1];
val = a[2];
May be this approach will be the best for such purpose:
var a = line.match(/([^:\s]+)\s*:\s*(.*)/);
var key = a[1];
var val = a[2];
So, you can use tabulations in your config/data files of such structure and also not worry about spaces before or after your name-value delimiter ':'.
Or you can use primitive and fast string functions indexOf and substr to reach your goal in, I think, the fastest way (by CPU and RAM)
for ( ... line ... ) {
var delimPos = line.indexOf(':');
if (delimPos <= 0) {
continue; // Something wrong with this "line"
}
var key = line.substr(0, delimPos).trim();
var val = line.substr(delimPos + 1).trim();
// Do all you need with this key: val
}
Split string in two at first occurrence
To split a string with multiple i.e. columns : only at the first column occurrence
use Positive Lookbehind (?<=)
const a = "Description: this: is: nice";
const b = "Name: My Name";
console.log(a.split(/(?<=^[^:]*):/)); // ["Description", " this: is: nice"]
console.log(b.split(/(?<=^[^:]*):/)); // ["Name", " My Name"]
it basically consumes from Start of string ^ everything that is not a column [^:] zero or more times *. Once the positive lookbehind is done, finally matches the column :.
If you additionally want to remove one or more whitespaces following the column,
use /(?<=^[^:]*): */
Explanation on Regex101.com
function splitOnce(str, sep) {
const idx = str.indexOf(sep);
return [str.slice(0, idx), str.slice(idx+1)];
}
splitOnce("description: this string is not escaped: i hate these colons", ":")

cut out part of a string

Say, I have a string
"hello is it me you're looking for"
I want to cut part of this string out and return the new string, something like
s = string.cut(0,3);
s would now be equal to:
"lo is it me you're looking for"
EDIT: It may not be from 0 to 3. It could be from 5 to 7.
s = string.cut(5,7);
would return
"hellos it me you're looking for"
You're almost there. What you want is:
http://www.w3schools.com/jsref/jsref_substr.asp
So, in your example:
Var string = "hello is it me you're looking for";
s = string.substr(3);
As only providing a start (the first arg) takes from that index to the end of the string.
Update, how about something like:
function cut(str, cutStart, cutEnd){
return str.substr(0,cutStart) + str.substr(cutEnd+1);
}
Use
substring
function
Returns a subset of a string between
one index and another, or through the
end of the string.
substring(indexA, [indexB]);
indexA
An integer between 0 and one less than the length of the string.
indexB
(optional) An integer between 0 and the length of the string.
substring extracts characters from indexA up to but not including indexB. In particular:
* If indexA equals indexB, substring returns an empty string.
* If indexB is omitted, substring extracts characters to the end
of the string.
* If either argument is less than 0 or is NaN, it is treated as if
it were 0.
* If either argument is greater than stringName.length, it is treated as
if it were stringName.length.
If indexA is larger than indexB, then the effect of substring is as if the two arguments were swapped; for example, str.substring(1, 0) == str.substring(0, 1).
Some other more modern alternatives are:
Split and join
function cutFromString(oldStr, fullStr) {
return fullStr.split(oldStr).join('');
}
cutFromString('there ', 'Hello there world!'); // "Hello world!"
Adapted from MDN example
String.replace(), which uses regex. This means it can be more flexible with case sensitivity.
function cutFromString(oldStrRegex, fullStr) {
return fullStr.replace(oldStrRegex, '');
}
cutFromString(/there /i , 'Hello THERE world!'); // "Hello world!"
s = string.cut(5,7);
I'd prefer to do it as a separate function, but if you really want to be able to call it directly on a String from the prototype:
String.prototype.cut= function(i0, i1) {
return this.substring(0, i0)+this.substring(i1);
}
string.substring() is what you want.
Just as a reference for anyone looking for similar function, I have a String.prototype.bisect implementation that splits a string 3-ways using a regex/string delimiter and returns the before,delimiter-match and after parts of the string....
/*
Splits a string 3-ways along delimiter.
Delimiter can be a regex or a string.
Returns an array with [before,delimiter,after]
*/
String.prototype.bisect = function( delimiter){
var i,m,l=1;
if(typeof delimiter == 'string') i = this.indexOf(delimiter);
if(delimiter.exec){
m = this.match(delimiter);
i = m.index;
l = m[0].length
}
if(!i) i = this.length/2;
var res=[],temp;
if(temp = this.substring(0,i)) res.push(temp);
if(temp = this.substr(i,l)) res.push(temp);
if(temp = this.substring(i+l)) res.push(temp);
if(res.length == 3) return res;
return null;
};
/* though one could achieve similar and more optimal results for above with: */
"my string to split and get the before after splitting on and once".split(/and(.+)/,2)
// outputs => ["my string to split ", " get the before after splitting on and once"]
As stated here: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/String/split
If separator is a regular expression that contains capturing parentheses, then each time separator is matched the results (including any undefined results) of the capturing parentheses are spliced into the output array. However, not all browsers support this capability.
You need to do something like the following:
var s = "I am a string";
var sSubstring = s.substring(2); // sSubstring now equals "am a string".
You have two options about how to go about it:
http://www.quirksmode.org/js/strings.html#substring
http://www.quirksmode.org/js/strings.html#substr
Try the following:
var str="hello is it me you're looking for";
document.write(str.substring(3)+"<br />");
You can check this link
this works well
function stringCutter(str,cutCount,caretPos){
let firstPart = str.substring(0,caretPos-cutCount);
let secondPart = str.substring(caretPos,str.length);
return firstPart + secondPart;
}

Categories

Resources