Remove operations using regex [duplicate] - regex

This question already has answers here:
How to find sum of integers in a string using JavaScript
(3 answers)
Closed 3 years ago.
I am getting a string back "1+2" and would like to remove the "+" and then add the numbers together.
Is this possible using Regex? So far I have:
let matches = pattern.exec(this.expression);
matches.input.replace(/[^a-zA-Z ]/g, "")
I am now left with two numbers. How would I add together?
"this.a + this.b"

Assuming the string returned only has '+' operation how about:
const sum = str.split('+').reduce((sumSoFar, strNum) => sumSoFar + parseInt(strNum), 0);

You cannot add two numbers using regex.
If what you have is a string of the form "1+2", why not simply split the string on the + symbol, and parseInt the numbers before adding them?
var str = "1+2";
var parts = str.split("+"); //gives us ["1", "2"]
console.log(parseInt(parts[0]) + parseInt(parts[1]));

If you don't always know what the delimiter between the two numbers is going to be you could use regex to get your array of numbers, and then reduce or whatever from there.
var myString = '1+2 and 441 with 9978';
var result = myString.match(/\d+/g).reduce((a,n)=> a+parseInt(n),0);
console.log(result); // 1 + 2 + 441 + 9978 = 10422
*Edit: If you actually want to parse the math operation contained in the string, there are a couple of options. First, if the string is from a trusted source, you could use a Function constructor. But this can be almost as dangerous as using eval, so it should be used with great caution. You should NEVER use this if you are dealing with a string entered by a user through the web page.
var myFormula = '1+2 * 441 - 9978';
var fn = new Function('return ' + myFormula);
var output = fn();
console.log(myFormula, ' = ', output); //1+2 * 441 - 9978 = -9095
A safer (but more difficult) course would be to write your own math parser which would detect math symbols and numbers, but would prevent someone from injecting other random commands that could affect global scope variables and such.

Related

Input Formatter Regex for simple mathematical calculation in Flutter/Dart

I want to ensure valid input on my text field where user can key in simple math expression for numbers up to 2 d.p such as "1.10 + 3.21 x 0.07". I am doing this through the adding regex to the input formatter constructor in the TextField class.
Following the regex example for 2 d.p here, I modified the code for my text field input formatter to include operators:
String dp = (decimalRange != null && decimalRange > 0)
? "([.][0-9]{0,$decimalRange}){0,1}"
: "";
String num = "($dp)|([0-9]{1,4}$dp)";
_exp = new RegExp(
"^($num){0,1}[-+x/]{0,1}($num){0,1}[-+x/]{0,1}($num){0,1}\$");
I am able to achieve "1.10 + 3.21 x 0.07", however, the user can also type invalid value into the textfield such as "1...10", "1.10 + 3..21". Any advice to improve the Regex above would be greatly appreciated!
Note that I also limit the user to key in a maximum of 3 decimal numbers. so "(2d.p)(operator)(2d.p)(operator)(2d.p)is the maximum limit.

Get the number between two characters - Typescript [duplicate]

This question already has answers here:
RegExp in TypeScript
(5 answers)
Closed 2 years ago.
I am new to Typescript and trying to make a webhook in my Google Cloud Functions.
I have a string: C1234567890A460450P10TS1596575969702
I want to use regex to extract the number 1234567890 from that string.
The first character C is fixed and does not change, the character A after the number is variable and can be any other alphabet.
The regex that matches the number is (?<=C)(\d{10})(?=\w).
I want to know how to execute this regex in Typescript so that I can get the number into a variable(eg: const number = [the number extracted from the string] //value 1234567890)
Edit 1:
Based on the provided suggestions (which I had tried already before posting this question), here is the code I could make out of it:
const string = request.body.string;
let regxp = new RegExp('(?<=C)(\d{10})(?=\w)');
const number = regxp.exec(string);
response.send(number);
This gives a blank response.
There is two problems, you never parsed the returned string to a number with parseInt and (?<=C) (positive lookbehind) is not always supported.
Second, your regular expression can be simplified into ^C\d{10} and a .splice(1) to remove the C.
const string: string = request.body.string;
const matches = s.match(/^C\d{10}/);
let number: number;
if(matches !== null) {
number = parseInt(matches[0].slice(1));
} else {
res.status(400).end(); // Assuming this is express
return;
}
res.send(number); // 1234567890
Playground

Actionscript RegExp positions and lengths of all matches in one call

How can I locate all positions of some word in text in one call using regular expressions in actionscript.
In example, I have this regular expression:
var wordsRegExp:RegExp = /[^a-zA-Z0-9]?(include|exclude)[^a-zA-Z0-9]?/g;
and it finds words "include" and "exclude" in text.
I am using
var match:Array;
match = wordsRegExp.exec(text)
to locate the words, but it finds first one first. I need to find all words "include" and "exclude" and there position so i do this:
var res:Array = new Array();
var match:Array;
while (match = wordsRegExp.exec(text)) {
res[res.length]=match;
}
And this does the trick, BUT very very slow for large amount of text. I was searching for some other method and didn't find it.
Please help and thanks in advance.
EDIT: I tried var arr:Array = text.match(wordsRegExp);
it finds all words, but not there positions in string
I think that's the nature of the beast. I don't know what you mean with "large amount of text", but if you want better performance, you should write your own parsing function. This shouldn't be that complicated, as your search expression is fairly simple.
I've never compared the performance of the String search functions and RegExp, because I thought there are based on the same implementation. If String.match() is faster, then you should try String.search(). With the index you could compute the substring for the next search iteration.
Found this on the help.adobe.com site,...
"Methods for using regular expressions with strings: The exec() method"
… The array also includes an index property, indicating the index position of the start of the substring match …
var pattern:RegExp = /\w*sh\w*/gi;
var str:String = "She sells seashells by the seashore";
var result:Array = pattern.exec(str);
while (result != null)
{
trace(result.index, "\t", pattern.lastIndex, "\t", result);
result = pattern.exec(str);
}
//output:
// 0 3 She
// 10 19 seashells
// 27 35 seashore

regex how can I split this word?

I have a list of several phrases in the following format
thisIsAnExampleSentance
hereIsAnotherExampleWithMoreWordsInIt
and I'm trying to end up with
This Is An Example Sentance
Here Is Another Example With More Words In It
Each phrase has the white space condensed and the first letter is forced to lowercase.
Can I use regex to add a space before each A-Z and have the first letter of the phrase be capitalized?
I thought of doing something like
([a-z]+)([A-Z])([a-z]+)([A-Z])([a-z]+) // etc
$1 $2$3 $4$5 // etc
but on 50 records of varying length, my idea is a poor solution. Is there a way to regex in a way that will be more dynamic? Thanks
A Java fragment I use looks like this (now revised):
result = source.replaceAll("(?<=^|[a-z])([A-Z])|([A-Z])(?=[a-z])", " $1$2");
result = result.substring(0, 1).toUpperCase() + result.substring(1);
This, by the way, converts the string givenProductUPCSymbol into Given Product UPC Symbol - make sure this is fine with the way you use this type of thing
Finally, a single line version could be:
result = source.substring(0, 1).toUpperCase() + source(1).replaceAll("(?<=^|[a-z])([A-Z])|([A-Z])(?=[a-z])", " $1$2");
Also, in an Example similar to one given in the question comments, the string hiMyNameIsBobAndIWantAPuppy will be changed to Hi My Name Is Bob And I Want A Puppy
For the space problem it's easy if your language supports zero-width-look-behind
var result = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "(?<=[a-z])([A-Z])", " $1");
or even if it doesn't support them
var result2 = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "([a-z])([A-Z])", "$1 $2");
I'm using C#, but the regexes should be usable in any language that support the replace using the $1...$n .
But for the lower-to-upper case you can't do it directly in Regex. You can get the first character through a regex like: ^[a-z] but you can't convet it.
For example in C# you could do
var result4 = Regex.Replace(result, "^([a-z])", m =>
{
return m.ToString().ToUpperInvariant();
});
using a match evaluator to change the input string.
You could then even fuse the two together
var result4 = Regex.Replace(#"thisIsAnExampleSentanceHereIsAnotherExampleWithMoreWordsInIt", "^([a-z])|([a-z])([A-Z])", m =>
{
if (m.Groups[1].Success)
{
return m.ToString().ToUpperInvariant();
}
else
{
return m.Groups[2].ToString() + " " + m.Groups[3].ToString();
}
});
A Perl example with unicode character support:
s/\p{Lu}/ $&/g;
s/^./\U$&/;

VB.Net Matching and replacing the contents of multiple overlapping sets of brackets in a string

I am using vb.net to parse my own basic scripting language, sample below. I am a bit stuck trying to deal with the 2 separate types of nested brackets.
Assuming name = Sam
Assuming timeFormat = hh:mm:ss
Assuming time() is a function that takes a format string but
has a default value and returns a string.
Hello [[name]], the time is [[time(hh:mm:ss)]].
Result: Hello Sam, the time is 19:54:32.
The full time is [[time()]].
Result: The full time is 05/06/2011 19:54:32.
The time in the format of your choice is [[time([[timeFormat]])]].
Result: The time in the format of your choice is 19:54:32.
I could in theory change the syntax of the script completely but I would rather not. It is designed like this to enable strings without quotes because it will be included in an XML file and quotes in that context were getting messy and very prone to errors and readability issues. If this fails I could redesign using something other than quotes to mark out strings but I would rather use this method.
Preferably, unless there is some other way I am not aware of, I would like to do this using regex. I am aware that the standard regex is not really capable of this but I believe this is possible using MatchEvaluators in vb.net and some form of recursion based replacing. However I have not been able to get my head around it for the last day or so, possibly because it is hugely difficult, possibly because I am ill, or possibly because I am plain thick.
I do have the following regex for parts of it.
Detecting the parentheses: (\w*?)\((.*?)\)(?=[^\(+\)]*(\(|$))
Detecting the square brackets: \[\[(.*?)\]\](?=[^\[+\]]*(\[\[|$))
I would really appreciate some help with this as it is holding the rest of my project back at the moment. And sorry if I have babbled on too much or not put enough detail, this is my first question on here.
Here's a little sample which might help you iterate through several matches/groups/captures. I realize that I am posting C# code, but it would be easy for you to convert that into VB.Net
//these two may be passed in as parameters:
string tosearch;//the string you are searching through
string regex;//your pattern to match
//...
Match m;
CaptureCollection cc;
GroupCollection gc;
Regex r = new Regex(regex, RegexOptions.IgnoreCase);
m = r.Match(tosearch);
gc = m.Groups;
Debug.WriteLine("Number of groups found = " + gc.Count.ToString());
// Loop through each group.
for (int i = 0; i < gc.Count; i++)
{
cc = gc[i].Captures;
counter = cc.Count;
int grpnum = i + 1;
Debug.WriteLine("Scanning group: " + grpnum.ToString() );
// Print number of captures in this group.
Debug.WriteLine(" Captures count = " + counter.ToString());
if (cc.Count >= 1)
{
foreach (Capture cap in cc)
{
Debug.WriteLine(string.format(" Capture found: {0}", cap.ToString()));
}
}
}
Here is a slightly simplified version of the code I wrote for this. Thanks for the help everyone and sorry I forgot to post this before. If you have any questions or anything feel free to ask.
Function processString(ByVal scriptString As String)
' Functions
Dim pattern As String = "\[\[((\w+?)\((.*?)\))(?=[^\(+\)]*(\(|$))\]\]"
scriptString = Regex.Replace(scriptString, pattern, New MatchEvaluator(Function(match) processFunction(match)))
' Variables
pattern = "\[\[([A-Za-z0-9+_]+)\]\]"
scriptString = Regex.Replace(scriptString, pattern, New MatchEvaluator(Function(match) processVariable(match)))
Return scriptString
End Function
Function processFunction(ByVal match As Match)
Dim nameString As String = match.Groups(2).Value
Dim paramString As String = match.Groups(3).Value
paramString = processString(paramString)
Select Case nameString
Case "time"
Return getLocalValueTime(paramString)
Case "math"
Return getLocalValueMath(paramString)
End Select
Return ""
End Function
Function processVariable(ByVal match As Match)
Try
Return moduleDictionary("properties")("vars")(match.Groups(1).Value)
Catch ex As Exception
End Try
End Function