Pattern match in javascript - javascript

In the below code Im not getting the right result. How can I can do pattern match in javascript?
function getPathValue(url, input) {
console.log("this is path key :"+input);
url = url.replace(/%7C/g, '|');
var inputarr = input.split("|");
if (inputarr.length > 1)
input = '\\b' + inputarr[0] + '\n|' + inputarr[1] + '\\b';
else
input = '\\b' + input + '\\b';
var field = url.search(input);
var slash1 = url.indexOf("/", field);
var slash2 = url.indexOf("/", slash1 + 1);
if (slash2 == -1)
slash2 = url.indexOf("?");
if (slash2 == -1)
slash2 = url.length;
console.log("this is path param value :"+url.substring(slash1 + 1, slash2));
return url.substring(slash1 + 1, slash2);
}
getPathValue("http://localhost/responsePath/mountainwithpassid|accesscode/100/mountainwithpassid|passid/1","mountainwithpassid|passid")
Im getting the below output
If I pass mountainwithpassid|accesscode as input Im getting output as
100. Same way if I pass
key :mountainwithpassid|passid value :100 // Expected output 1

If your intention is to simply retrieve the value in the path that follows the input (contained within '/') then you can achieve this with a simpler regular expression. First you will need a method to escape your input string since it contains a pipe character '|' which is translated as OR in regex.
You can use this (taken from https://stackoverflow.com/a/3561711):
RegExp.escape= function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
Then your getPathValue function can look something like:
function getPathValue(url, input) {
var pathValue = null;
var escapedInput = RegExp.escape(input);
// The RegExp below extracts the value that follows the input and
// is contained within '/' characters (the last '/' is optional)
var pathValueRegExp = new RegExp(".*" + escapedInput + "/([^/]+)/?.*", 'g');
if (pathValueRegExp.test(url)) {
pathValue = url.replace(pathValueRegExp, '$1');
}
return pathValue;
}
You will also need to think about how you handle errors - in the example a null value is returned if no match is found.

I'm trying to understand the question. Given a URL of:
"http://localhost/responsePath/mountainwithpassid|accesscode/100/mountainwithpassid|passid/1"
and an argument of:
"mountainwithpassid|passid"
you expect a return value of:
"1"
An argument of
"mountainwithpassid|accesscode"
should return:
"100"
Is that correct? If so (and I'm not certain it is) then the following may suit:
function getPathValue(url, s) {
var x = url.indexOf(s);
if (x != -1) {
return url.substr(x).split('/')[1];
}
}
var url = "http://localhost/responsePath/mountainwithpassid|accesscode/100/mountainwithpassid|passid/1";
var x = "mountainwithpassid|passid";
var y = "mountainwithpassid|accesscode";
console.log(getPathValue(url, x)); // 1
console.log(getPathValue(url, y)); // 100

Related

Javascript method to convert string value

Can someone please help me to write a JS method which takes a String value like
/Content/blockDiagram/0/bundle/0/selectedBundle
/Content/blockDiagram/1/bundle/1/selectedBundle
/Content/blockDiagram/0/bundle
and convert it to
/Content/blockDiagram[1]/bundle[1]/selectedBundle
/Content/blockDiagram[2]/bundle[2]/selectedBundle
/Content/blockDiagram[1]/bundle
It is basically taking the number in the path and increment it by 1 and then changing the structure of the string.
My attempt
function setReplicantPartListOptions(list) {
list = "/" + list;
var index = list.lastIndexOf("/");
var tempString = list.substring(0, index);
var index2 = tempString.lastIndexOf("/");
var initialString = list.substring(0, index2);
var result = tempString.substring(index2 + 1, index) var middlevalue = parseFloat(result) + 1
var lastString = list.substring(index, list.length);
list = initialString + "[" + middlevalue + "]" + lastString;
return list;
}
simple regular expression with capture group with replace
var str = "/Content/blockDiagram/0/bundle/0/selectedBundle"
var updated = str.replace(/\/(\d+)/g, function (m, num) {
var next = +num + 1; // convert string to number and add one
return "[" + next + "]"; //return the new string
})
console.log(updated)
String.replace(RegExp, callback(match, contents)) is the callback version of String.replace().
In my case, the first parameter of callback function is the result/match. It takes the match and converts it to number using + operator, and then increment it by one. Finally, I add [ ] around the value and return it!
let str = "/Content/blockDiagram/0/bundle/0/selectedBundle"
console.log(
str.replace(/\b\d+\b/g, match => `[${ +match + 1 }]`)
);
var str = "/Content/blockDiagram/0/bundle/0/selectedBundle"
console.log(
str.replace(/\/(\d+)\//g, function(_,num) { return `[${++num}]`})
)

How to match two patterns with a space between them in JavaScript?

I know how to match one pattern using JavaScript:
var pattern = somePattern
if (!pattern.test(email)) { //do something }
but what if I have to match 2 patterns with a space between them so if I have this:
word1 word2
word1 should match pattern1
word2 should match pattern2
a space should be between them
How can I achieve this using JavaScript?
word1word2 is refused (even if they much pattern1 and pattern2 in order, because of the lack of space)
word1 should be an IP; word2 should be a number
Some examples:
172.30.10.10 10 (acceptable)
172.30.10.1010 (not acceptable)
10 10 (not acceptable)
10 172.30.10.10 (not acceptable)
According to the documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
The RegExp object has a source property, which returns a string representation of the regex.
Here's an example.
var validName = /\w+ \w+/
var validEmail = /[^# ]+#.+\..+/
var combined = new RegExp(validName.source + ' ' + validEmail.source);
console.log(combined.test('John Doe jdoe#example.com'));
// outputs true
console.log(combined.test('John Doe bademail#'));
// outputs false
However, keep in mind that this solution will NOT work if the regexes include boundary markers like $ and ^.
Combine it into a single pattern:
var pattern = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+\d{1,}/;
var test= '172.30.10.10 10';
var matched = test.match(pattern);
http://regex101.com/r/kU9cN3/3
UPDATE further to Brian's comment. If they need to be coded as separate patterns you can do as follows. This may be useful if you want to re-use patterns or make other combinations.
var ip = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/,
number = /\d{1,}/,
combinedRegExp = new RegExp(ip.source+' '+number.source);
var testString = '172.30.10.10 10';
var result = combinedRegExp.test(testString);
console.log(result);//true
http://jsfiddle.net/7Lrsxov8/
Building on Joe Frambach's answer, you could perform some sanity checking on the input:
function combinePatterns(pattern1, pattern2, options) {
if (pattern1.constructor != RegExp || pattern2.constructor != RegExp) {
throw '`pattern1` and `pattern2` must be RegExp objects';
}
var pattern1_str = pattern1.source;
var pattern2_str = pattern2.source;
options = options || {};
// Ensure combining the patterns makes something sensible
var p1_endOfLine, p2_startOfLine;
if (pattern1_str.lastIndexOf('$') == pattern1_str.length - 1) {
p1_endOfLine = true;
if (options.stripBadDelimiters || options.swapBadDelimiters) {
pattern1_str = pattern1_str.substr(0, pattern1_str.length - 1);
}
if (options.swapBadDelimiters
&& pattern2_str.lastIndexOf('$') != pattern2_str.length - 1) {
pattern2_str += '$';
}
}
if (pattern2_str.indexOf('^') == 0) {
p2_startOfLine = true;
if (options.stripBadDelimiters || options.swapBadDelimiters) {
pattern2_str = pattern2_str.substr(1);
}
if (options.swapBadDelimiters && pattern1_str.indexOf('^') != 0) {
pattern1_str = '^' + pattern1_str;
}
}
if (p1_endOfLine && p2_startOfLine && options.swapPatterns) {
var tmp = pattern1_str;
pattern1_str = pattern2_str;
pattern2_str = tmp;
}
return new RegExp(pattern1_str + ' ' + pattern2_str);
}
var first = combinePatterns(/abc/, /123/);
var second = combinePatterns(/abc$/, /^123/);
var third = combinePatterns(/abc$/, /^123/, { stripBadDelimiters: true });
var fourth = combinePatterns(/abc$/, /^123/, { swapBadDelimiters: true });
var fifth = combinePatterns(/abc$/, /^123/, { swapPatterns: true });
// first = /abc 123/
// second = /abc$ ^123/
// third = /abc 123/
// fourth = /^abc 123$/
// fourth = /^123 abc$/
This isn't the end-all be-all of what you can do to help ensure your input produces the desired output, but it should illustrate the sorts of possibilities that are open to you when reconstructing the regex pattern in this fashion.
A bit more compact and complete solution:
var ipNum = "\\d{1,3}";
var ip = "(" + ipNum + "\\.){3}" + ipNum;
var num = "\\d+";
var ipRE = new RegExp("^\\s*" + ip + "\\s+" + ipNum + "\\s*$");
console.log(ipRE.test(" 172.30.10.10 10 ")); // true

Parse and replace a string in JavaScript?

I've a HTML string that looks as follows
var hoverData = "<table id='hvr-revision_history'><tr><td>{date_value}2013-07-29T11:52:38Z{date_value}</td><td>Error1</td></tr><tr><td>{date_value}2013-07-30T11:52:38Z{date_value}</td><td>Error2</td></tr><tr><td>{date_value}2013-07-31T11:52:38Z{date_value}</td><td>Error3</td></tr></table>";
The final output needed is
"<table id='hvr-revision_history'><tr><td>07/29/2013 11:52:38 AM</td><td>Error1</td></tr><tr><td>07/30/2013 11:52:38 AM</td><td>Error2</td></tr><tr><td>07/31/2013 11:52:38 AM</td><td>Error3</td></tr></table>"
My approach is
var sindex = 0;
while(true){
var sindex = hoverData.indexOf("{date_value}"); //startindex
if(sindex <0)
break;
var eindex = hoverData.indexOf("{date_value}",sindex+1); //endindex
var date = hoverData.substring(sindex+12,eindex); //string between {date_value} tags, so 2013-07-29T11:52:38Z
//logic to parse the date
var hoverData = hoverData.replace(date,parsedDate);
}
var hoverData = hoverData.replace("{date_value}","");
Is there a better approach?
My code will fail if I've 2 or more dates that are exactly the same.
You can match the individual date chunks as a regular expression, with a function (instead of a string) as the replacement. That function can call your parse function, which I've stubbed out here since you didn't include it.
var hoverData = "<table id='hvr-revision_history'><tr>" +
"<td>{date_value}2013-07-29T11:52:38Z{date_value}</td>" +
"<td>Error1</td></tr>" +
"<tr><td>{date_value}2013-07-30T11:52:38Z{date_value}</td>" +
"<td>Error2</td></tr>" +
"<tr><td>{date_value}2013-07-31T11:52:38Z{date_value}</td>" +
"<td>Error3</td></tr></table>";
// your "logic to parse the date" would go here
function parseDate(str) {
return "( parsed " + str + " )";
}
// look for our delimiters with *only* the legal timestamp
// characters between them
hoverData = hoverData.replace(/\{date_value\}([A-Z0-9\-\:]+)\{date_value\}/g,
// match gets the fully-matched string, plus any captured patterns
// (the parenthesized chunk) as separate parameters. `datepart` will
// contain the matched timestamp string only
function (match, datepart) {
return parseDate(datepart);
}
);
hoverData = hoverData.replace("{date_value}","");
See it in action here: http://codepen.io/paulroub/pen/CGqlh

replace HTML text with incrementing numbers in javascript

I have a bunch of text with no HTML, and I'm trying to find all replace all instances of String with <span id="x">String</span>
The catch is I'm trying to increment x every time to get a bunch of uniquely identifiable spans rather then identical ones.
I have no problem getting all instances of String, but for the life of me I can't get the increment to work. All help I can find seems to be directed towards doing the opposite of this.
Any ideas what I can do or where else to turn for help?
EDIT:
This is targeting a div with ID 'result' that contains only text.
var target = "String";
var X = //the number I was trying to increment
var re = new RegExp(" " + target + " ","g");
document.getElementById('result').innerHTML = document.getElementById('result').innerHTML.replace(re, '<span id="' + X + '">' + target + '</span>');
I'm guessing you are using a regex, which is fine, but you can specify a function as the second parameter to replace and do your logic there.
The MDN documentation for doing this is here - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter
You could use something like this:
http://jsfiddle.net/gjrCN/2/
function replacer(orig, target) {
var x = 0;
var re = new RegExp(target, "g");
var ret = orig.replace(re, function (match) {
return "<span id='" + (++x) + "'>" + match + "</span>";
});
return ret;
}
var example = "String Stringasdf String2344 String";
var replaced = replacer(example, "String");
console.log(replaced);
You can change ++x to x++ if you want the counting to start at 0 instead of 1.
With reference to these docs.
You can pass a function to the String.replace method would allow you to increment a counter with each call and use that to set your ID:
var forReplacements = "I do like a String that's a nice long String with Strings in it";
var incrementer = (function() {
var counter = -1;
var fn = function(match) {
counter++;
return "<span id='"+counter+"'>"+match+"</span>";
};
fn.reset = function() {
counter = -1;
}
return fn;
}());
var newString = forReplacements.replace(/String/g, incrementer )
See this fiddle to see it in action

Looking for a regex to parse parameters string for JS

I cannot find out the regex to get param value from the part of query string:
I need to send parameter name to a method and get parameter value as result for string like
"p=1&qp=10".
I came up with the following:
function getParamValue(name) {
var regex_str = "[&]" + name + "=([^&]*)";
var regex = new RegExp(regex_str);
var results = regex.exec(my_query_string);
// check if result found and return results[1]
}
My regex_str now doesn't work if name = 'p'. if I change regex_str to
var regex_str = name + "=([^&]*)";
it can return value of param 'qp' for param name = 'p'
Can you help me with regex to search the beginning of param name from right after '&' OR from the beginning of a string?
This might work, depending on if you have separated the parameter part.
var regex_str = "(?:^|\&)" + name + "=([^&]*)";
or
var regex_str = "(?:\&|\?)" + name + "=([^&]*)";
Looks like split will work better here:
var paramsMap = {};
var params = string.split("&");
for (var i = 0; i < params.length; ++i) {
var keyValue = params[i].split("=", 2);
paramsMap[keyValue[0]] = keyValue[1];
}
If you desperately want to use a regex, you need to use the g flag and the exec method. Something along the lines of
var regex = /([^=]+)=([^&]+)&?/g;
var paramsMap = {};
while (true) {
var match = regex.exec(input);
if (!match)
break;
paramsMap[match[1]] = match[2];
}
Please note that since the regex object becomes stateful, you either need to reset its lastIndex property before running another extraction loop or use a new RegExp instance.
Change your regex string to the following:
//pass the query string and the name of the parameter's value you want to retrieve
function getParamValue(my_query_string , name)
{
var regex_str = "(?:^|\&)" + name + "\=([^&]*)";
var regex = new RegExp(regex_str);
var results = regex.exec(my_query_string);
try
{
if(results[1] != '')
{
return results[1];
}
}
catch(err){};
return false;
}

Categories