Regex to match SVG path data in javascript - javascript

var string = "M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z";
var regex = "[a-zA-Z][0-9, /-/.]*";
var array = string.match(regex);
Can anyone help me with my regular expression to match individual intructions (array[0] == "M-84.1487,-15.8513"; array[1] == "a22.4171,22.4171 0 1 0 0,31.7026";)
Thanks a lot

According to the BNF description you can identify an instruction as a letter followed by anything that is not a letter.
var pathData = "M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z";
var pathSegmentPattern = /[a-z][^a-z]*/ig;
var pathSegments = pathData.match(pathSegmentPattern);
Of course you may want to trim the results, but that shouldn't be too hard.
Also try not to name your variables so meaningless (string, regex, array). In my opinion that's worse than naming them a, b or c.

Related

GLPK.js no primal feasible solution when a solution exists

I am using the glpk.js library in an Angular application to solve an ILP problem. I have been using the library for some time now and it usually works well. I have encountered similar issues in the past, but I was able to sidestep them without finding out why they occurred. It might very well be the case, that I am not using the library correctly as their documentation is quite lacking.
I construct a "base" ILP problem and then I iterate over some array, construct additional constraints depending on each element of my array and try to solve the base ILP with the new constrains for each element.
I know there is a solution for each of the ILPs, but the solver returns PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION for all but one of the ILPs.
My base ILP (in human readable format):
p0 >= 0
p1 >= 0
p2 >= 0
p3 >= 0
p4 >= 0
p5 >= 0
p6 >= 0
p7 >= 0
p0 +p1 +p2 +p3 +p4 +p5 +p6 +p7 >= 1
p1 -p0 -rise0 = 0
p2 +p3 -p1 -rise1 = 0
p4 -p2 -rise2 = 0
p6 -p4 -rise3 = 0
p10 -p6 -p5 -rise4 = 0
p5 -p3 -rise5 = 0
where the objective function is to minimise the sum of the p-variables.
when I apply the following additional constraints, the solver returns a solution (p10 = 1, all other p = 0):
rise0 = 0
rise1 = 0
rise2 = 0
rise3 = 0
rise4 = 1
rise5 = 0
p0 = 0
when I apply the following additional constraints, the solver returns no solution, even if p0 = 1, all other p = 0, solves the ILP:
rise0 = -1
rise1 = 0
rise2 = 0
rise3 = 0
rise4 = 0
rise5 = 0
p0 = 1
all the other sets of constrains also contain some rise with a negative value, which seems to cause the issue.
I am using the following configuration as input to the solver (JSON for the second example ILP):
{
"name":"p0",
"objective": {
"direction":1,
"name":"region",
"vars": [
{"name":"p0","coef":1},
{"name":"p1","coef":1},
{"name":"p2","coef":1},
{"name":"p3","coef":1},
{"name":"p4","coef":1},
{"name":"p5","coef":1},
{"name":"p6","coef":1},
{"name":"p7","coef":1}
]
},
"subjectTo": [
{"name":"c0","vars":[{"name":"p0","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c1","vars":[{"name":"p1","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c2","vars":[{"name":"p2","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c3","vars":[{"name":"p3","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c4","vars":[{"name":"p4","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c5","vars":[{"name":"p5","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c6","vars":[{"name":"p6","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c7","vars":[{"name":"p7","coef":1}],"bnds":{"type":2,"ub":0,"lb":0}},
{"name":"c8","vars":[{"name":"p0","coef":1},{"name":"p1","coef":1},{"name":"p2","coef":1},{"name":"p3","coef":1},{"name":"p4","coef":1},{"name":"p5","coef":1},{"name":"p6","coef":1},{"name":"p7","coef":1}],"bnds":{"type":2,"ub":0,"lb":1}},
{"name":"c9","vars":[{"name":"p1","coef":1},{"name":"p0","coef":-1},{"name":"rise0","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c10","vars":[{"name":"p2","coef":1},{"name":"p3","coef":1},{"name":"p1","coef":-1},{"name":"rise1","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c11","vars":[{"name":"p4","coef":1},{"name":"p2","coef":-1},{"name":"rise2","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c12","vars":[{"name":"p6","coef":1},{"name":"p4","coef":-1},{"name":"rise3","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c13","vars":[{"name":"p7","coef":1},{"name":"p6","coef":-1},{"name":"p5","coef":-1},{"name":"rise4","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c14","vars":[{"name":"p5","coef":1},{"name":"p3","coef":-1},{"name":"rise5","coef":-1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c15","vars":[{"name":"rise0","coef":1}],"bnds":{"type":5,"ub":-1,"lb":-1}},
{"name":"c16","vars":[{"name":"rise1","coef":1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c17","vars":[{"name":"rise5","coef":1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c18","vars":[{"name":"rise2","coef":1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c19","vars":[{"name":"rise3","coef":1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c20","vars":[{"name":"rise4","coef":1}],"bnds":{"type":5,"ub":0,"lb":0}},
{"name":"c21","vars":[{"name":"p0","coef":1}],"bnds":{"type":5,"ub":1,"lb":1}}
],
"binaries":[],
"generals": ["p0","p1","p2","p3","p4","p5","p6","p7","rise0","rise1","rise2","rise3","rise4","rise5"]
}
I assumed all integers (including negative) are allowed as solutions. But the only logical explanation to my problem seems to be that this is not the case. How can I enable negative integers as possible solutions?
I should have just researched the library more. There is an issue in the repository of the library that answers my question.
It really is the case that variables are bound to non-negative integers.
Variables with negative values can be expressed by splitting them into a positive and a negative part.
In my case it means I have to create a rise0plus and a rise0minus variable and modify my constrains as follows (for each rise variable):
p1 - p0 -rise0plus +rise0minus = 0
...
rise0plus -rise0minus = -1

How do I find the index of a substring within a string in Javascript from a position otther than the string start?

I'm trying to some string manipulation using javascript/jquery.
How do I find the position of a substring within a string starting at a position somewhere in the middle of the string?
Consider the following string:
"Item1 100 Item2 200"
If I know the index of the starting point of "100" (the position of "1") within the string, how do I find the index of the 1st space which occurs after this?
So what I'm really looking for is the index of the space that occurs before "200".
I know in C#/VB.Net there are robust string libraries which allow me to easily slice and dice the string.
How do I accomplish this using jquery/javascript?
Thanks,
JohnB
indexOf() takes a second parameter indicating where to start. So if you know where you want to start, you can just pass that in:
let s = "Item1 100 Item2 200"
let i100 = 6 // known index of 100
let ind = s.indexOf(" ", i100) // start looking at 6
console.log(ind)
You could use a for loop with the indexOf() function if you want to find the indices of all the 'space' instances.
Hope the snippet helps give an idea.
button {
margin: 5px;
padding: 4px;
}
#index {
margin-left: 10px;
}
<button onclick="find();">
Reveal indices
</button>
<br>
<p id="index"></p>
<script>
function find() {
var str = "Item1 100 Item2 200";
var j = [];
var i = 0;
for (i = 0; i <= str.length; i++) {
var n = str.indexOf(" ", i);
const isInArray = j.includes(n);
if (!isInArray && n > 0) {
j.push(n);
}
}
document.getElementById("index").innerHTML = j;
}
</script>
"So what I'm really looking for is the index of the space that occurs before "200"."
If you plan on indexing spaces then referencing the position of 100 should be 3, either way the space after 100 is not the space before 200. Therefore I will accept your second statement as the predicate.
findSpace(string, term, start, after)
param 1: string to search through
param 2: term string to find
param 3: start index to start from -- defaults to 0
param 4: after find the space after term -- defaults to false
It finds the space before the substring if found and returns the index of the space.
The key to including each space as an array element is to pass a regex that captures whitespace as the delimiter to the .split((\s)) method. Then use .indexOf() method to extract the index of the given term -1.
var string = "Item1 100 Item2 200 Item11 1100 Item32 8010";
function findSpace(string, term, start = 0, after = false) {
var arrayA = string.split(/(\s)/);
console.log(arrayA);
let index = arrayA.indexOf(term, start);
return after ? index + 1 : index - 1;
}
console.log(findSpace(string, '200', 1, false));

How to create regex for passwords validate with length 8 - 24 and contain at least 3 of the following: lowercase, uppercase, numbers, special char

I want to use java-script to validate following criteria for password.
a.A password of at least 8 and no more than 24 characters is required.
b.Every password must contain at least three of these four types of characters:
1.an upper case letter
2.a lower case letter
3.a number
4.a special character.
I have found this code which is really easy and hand-full but it is just checking all 4 conditions not just at-least 3 conditions out of 4.
"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&])[A-Za-z\d$#$!%*?&]{8,24}"
I will really appreciate if you help me to figure out to create javascript validation on password to full fill my above requirement.
Thank you all for your help. I have modified #Ehtesham code and achieved the functionality.
function isValidPassword(pass) {
var lowerRegex = /[a-z]/;
var upperRegex = /[A-Z]/;
var numberRegex = /[0-9]/;
var specialRegex = /[$#$!%*?&]/;
var count = 0;
if (pass.length < 8 || pass.length > 24) {
return false;
}
if (pass.match(lowerRegex)){count += 1;}
if (pass.match(upperRegex)){count += 1;}
if (pass.match(numberRegex)){count += 1;}
if (pass.match(specialRegex)){count += 1;}
if (count >= 3){
return true;
}else{
return false;
}
}
The regex you provided is made out of 5 major parts:
The pattern validating the length: [A-Za-z\d$#$!%*?&]{8,24}
A positive lookahead for at least one lowercase: (?=.*[a-z])
A positive lookahead for at least one uppercase: (?=.*[A-Z])
A positive lookahead for at least one number: (?=.*\d)
A positive lookahead for at least one special char: (?=.*[$#$!%*?&])
Now, you only want to apply 3 out of the 4 positive lookaheads. Since lookaheads are non-consuming matches, the cursor of the regex-engine will remain unchanged, as the matching is going on. (Using positive Lookaheads this way is often used to generate AND-Patterns)
So, you now have 4 conditions and you want that only 3 of them are matched. As described, it would be easy to use independent expressions and check if 3 apply. However, some native features (for instance jsf's f:validateRegex) only work with a single pattern.
Regular Expressions are supporting OR in a native way: | - hence to turn your expression 1 AND 2 AND 3 AND 4 into a minimum requirement of matching 3 of them, you could use an expression like (1 AND 2 AND 3) OR (1 AND 2 AND 4) OR (1 AND 3 AND 4) OR (2 AND 3 AND 4), which would cover all usecases required:
1 2 3 4
1 1 1 0
1 1 0 1
1 0 1 1
0 1 1 1
So, to match all this within a single pattern, just rearange your lookaheads as required:
^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[$#$!%*?&])|(?=.*[a-z])(?=.*\d)(?=.*[$#$!%*?&])|(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&]))[A-Za-z\d$#$!%*?&]{8,24}$
Drilldown:
^(?: - non matching group
(?=.*[a-z])(?=.*[A-Z])(?=.*\d) - one lower, one upper, one number
| - or
(?=.*[a-z])(?=.*[A-Z])(?=.*[$#$!%*?&]) - one lower, one upper, one special
| - or
(?=.*[a-z])(?=.*\d)(?=.*[$#$!%*?&]) - one lower, one number, one special
| - or
(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&]) - one upper, one number, one special
)
[A-Za-z\d$#$!%*?&]{8,24}$ - 8 to 24 chars.
(Debuggex is using javascript)
^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[$#$!%*?&])|(?=.*[a-z])(?=.*\d)(?=.*[$#$!%*?&])|(?=.*[A-Z])(?=.*\d)(?=.*[$#$!%*?&]))[A-Za-z\d$#$!%*?&]{8,24}$
Debuggex Demo
Please consider bookmarking the Stack Overflow Regular Expressions FAQ for future reference. There is a password validation entry under
"Common validation tasks > Internet"
That said, this seems like a pretty easy task if you break it up, as others have suggested. Mashing up all those requirements into a single regex, although an interesting exercise, is overkill in my opinion.
(This is Java, but there are equivalent concepts in JavaScript.)
public bolean isPasswordValid(String password) {
if(!length in bounds) {
return false;
}
boolean hasUpper = Pattern.compile("[a-z]").find(password);
boolean hasLower = Pattern.compile("[A-Z]").find(password);
boolean hasDigit = Pattern.compile("[0-9]").find(password);
boolean hasSpecialChar = Pattern.compile("...NOT SURE OF THIS ONE...").find(password);
int types = (hasUpper ? 1 : 0) + (hasLower ? 1 : 0) +
(hasDigit ? 1 : 0) + (hasSpecialChar ? 1 : 0);
return (types >= 3);
}
And if this is a function that will be used rapid fire, then you'll likely want to pre-compile and store those Matchers.
In javascript you can use following simple function.
function isValidPassword(pass) {
var lowerRegex = /[a-z]/;
var upperRegex = /[A-Z]/;
var numberRegex = /[0-9]/;
var specialRegex = /[$#$!%*?&]/;
if (pass.length < 8 || pass.length > 24) {
return false;
}
if (pass.match(lowerRegex) && pass.match(upperRegex) &&
pass.match(numberRegex) && pass.match(specialRegex)) {
return true;
}
return false;
}
Jsfiddle demo
This builds on Ehtesham's answer to require 3 out of 4:
function isValidPassword(pass) {
var lowerRegex = /[a-z]/;
var upperRegex = /[A-Z]/;
var numberRegex = /[0-9]/;
var specialRegex = /[$#$!%*?&]/;
var mustBe3 = 0;
if(pass.length < 9 || pass.length > 24) { return false; }
if(pass.match(lowerRegex)) { mustBe3 ++; }
if(pass.match(upperRegex)) { mustBe3 ++; }
if(pass.match(numberRegex)) { mustBe3 ++; }
if(pass.match(specialRegex)){ mustBe3 ++; }
// for testing ...
if(window.console) console.log('pass: '+pass+' mustBe3: '+mustBe3);
if( mustBe3 >= 3 ) { return true; }
return false;
}

Creating a string of digits in javascript each within a limit

How can I use javascript to randomly create a 20 digit string of numbers, each of the digits ranging only between 1 and 5?
An example would be: 52431425331425141521
As well as the logical algorithm I gave in my comment above, you could just use this one-liner:
var result = Math.floor(Math.random()*95367431640625).toString(5)
.split("").map(function(n) {return +n+1;}).join("");
Essentially, pick a random integer between 0 and 520-1, convert it to base 5, then increment all the digits by one, so they're all between 1 and 5 ^_^
EDIT: Just realised this won't handle low numbers too well. Try this:
var result = (
new Array(20).join("0")
+
Math.floor(Math.random()*95367431640625).toString(5)
).slice(-20).split("").map(function(n) {return +n+1;}).join(""));
This does basically the same, except it prepends 19 zeroes to the front of your number, then slices off the last 20 characters. This will allow it to handle leading zeroes correctly to give a 20-digit number in all cases.
You can use this:
function random_string()
{
var text = "";
var string = "12345";
for( var i=0; i < 20; i++ )
text += string.charAt(Math.floor(Math.random() * string.length));
return text;
}
random_string();

Regex for 1-10 in javascript for validation

What would be the regex for numbers ranging 1-10 and 1-5? Please help this troubled soul.
You could achive that with easy number checks in javascript:
// Convert input to integer just to be sure
mynum = parseInt(mynum, 10);
// Check number-range
if(mynum >= 1 && mynum <=10)
and
if(mynum >= 1 && mynum <=5)
If you really want to use regex:
/^([1-9]|10)$/
and
/^[1-5]$/
UPDATE:
Fixed the first regex to correctly match the string boundings
Added parseInt to the first example to ensure correct number-checks
This is not a good use of Regular Expressions.
Use simple conditions:
if (x > 0 && x < 6) {
// x is 1 - 5
}
if (x > 0 && x < 10) {
// x is 1 - 10
}
For 1-5 you only need to enclose it as character class:
/^[1-5]$/
For 1-10 you'd just need an additional alternative:
/^([1-9]|10)$/
Is there a reason you want to use regular expressions?
/([1-9]|10)/
Use numeric comparison. The following Number extension can check if a number falls between 2 values:
Number.prototype.between =
function(lower,upper, includeBoundaries){
lower = Number(lower);
upper = Number(upper);
noCando = isNaN(lower) ||
isNaN(upper) ||
lower>=upper;
if ( noCando ) {
throw 'wrong arguments or out of range';
}
return includeBoundaries
? this >= lower && this <= upper
: this > lower && this < upper
};
// usage:
(12).between(1,12); /=> false
(12).between(1,12,true); /=> true
(12).between(0,15,true); /=> true
(0).between(-5,1); //=> true
The function converts the parameters to Number because 0 can evaluate to a boolean in javascript, to be able to check if the paramaters are real number values and to be able to check if lower is not greater than/equal to upper. In those cases an error is thrown.
The includeBoundaries parameter also checks if a Number is equal to lower or upper, if it's not supplied, the function returns a real 'between'-check.
For 1-10 it can be
/^([1-9]|10)$/
and for 1-5 simply
/^[1-5]$/
The answer would be
/^([1-9]|10)$/

Categories