How can I add the multiplication sign to an algebraic expression through regex? - regex

I am writing a mathematical parser in which a user can enter answers to be evaluated. How can I convert something like 'xe^x + xyz' to 'x*e^x + x*y*z' through Regex?
Alternative methods would be welcome too. Thank you!

Look for each occurrence of:
(?<=[a-zA-Z0-9])(?=[a-zA-Z])
Replace by:
*
Edit:
As pointed out by #ChristopherCreutzig, this regex will also handle the cases like 23xy in the most probable expected way. That is:
considering a sequence of digits as a part of a single expressoin,
considering a digit followed by a letter as a multiplication,
considering a letter followed by a digit as part of a single expression.
For example, for this input:
2x1 + 3xy
The resulting output is:
2*x1 + 3*x*y
See it in action and try it out live here on regex101.

(?<=\w)(?=\w)
(looking one letter before and after)
replace by
*

Related

Can you restrict two characters based on their ASCII order in regex?

Let's say I have a string of 2 characters. Using regex (as a thought exercise), I want to accept it only if the first character has an ascii value bigger than that of the second character.
ae should not match because a is before e in the the ascii table.
ea, za and aA should match for the opposite reason
f$ should match because $ is before letters in the ascii table.
It doesn't matter if aa or a matches or not, I'm only interested in the base case. Any flavor of regex is allowed.
Can it be done ? What if we restrict the problem to lowercase letters only ? What if we restrict it to [abc] only ? What if we invert the condition (accept when the characters are ordered from smallest to biggest) ? What if I want it to work for N characters instead of 2 ?
I guess that'd be almost impossible for me to do it then, however bobble-bubble impressively solved the problem with:
^~*\}*\|*\{*z*y*x*w*v*u*t*s*r*q*p*o*n*m*l*k*j*i*h*g*f*e*d*c*b*a*`*_*\^*\]*\\*\[*Z*Y*X*W*V*U*T*S*R*Q*P*O*N*M*L*K*J*I*H*G*F*E*D*C*B*A*#*\?*\>*\=*\<*;*\:*9*8*7*6*5*4*3*2*1*0*\/*\.*\-*,*\+*\**\)*\(*'*&*%*\$*\#*"*\!*$(?!^)
bobble bubble RegEx Demo
Maybe for abc only or some short sequences we would approach solving the problem with some expression similar to,
^(abc|ab|ac|bc|a|b|c)$
^(?:abc|ab|ac|bc|a|b|c)$
that might help you to see how you would go about it.
RegEx Demo 1
You can simplify that to:
^(a?b?c?)$
^(?:a?b?c?)$
RegEx Demo 2
but I'm not so sure about it.
The number of chars you're trying to allow is irrelevant to the problem you are trying to solve:
because you can simply add an independent statement, if you will, for that, such as with:
(?!.{n})
where n-1 would be the number of chars allowed, which in this case would be
(?!.{3})^(?:a?b?c?)$
(?!.{3})^(a?b?c?)$
RegEx Demo 3
A regex is not the best tool for the job.
But it's doable. A naive approach is to enumerate all the printable ascii characters and their corresponding lower range:
\x21[ -\x20]|\x22[ -\x21]|\x23[ -\x22]|\x24[ -\x23]|\x25[ -\x24]|\x26[ -\x25]|\x27[ -\x26]|\x28[ -\x27]|\x29[ -\x28]|\x2a[ -\x29]|\x2b[ -\x2a]|\x2c[ -\x2b]|\x2d[ -\x2c]|\x2e[ -\x2d]|\x2f[ -\x2e]|\x30[ -\x2f]|\x31[ -\x30]|\x32[ -\x31]|\x33[ -\x32]|\x34[ -\x33]|\x35[ -\x34]|\x36[ -\x35]|\x37[ -\x36]|\x38[ -\x37]|\x39[ -\x38]|\x3a[ -\x39]|\x3b[ -\x3a]|\x3c[ -\x3b]|\x3d[ -\x3c]|\x3e[ -\x3d]|\x3f[ -\x3e]|\x40[ -\x3f]|\x41[ -\x40]|\x42[ -\x41]|\x43[ -\x42]|\x44[ -\x43]|\x45[ -\x44]|\x46[ -\x45]|\x47[ -\x46]|\x48[ -\x47]|\x49[ -\x48]|\x4a[ -\x49]|\x4b[ -\x4a]|\x4c[ -\x4b]|\x4d[ -\x4c]|\x4e[ -\x4d]|\x4f[ -\x4e]|\x50[ -\x4f]|\x51[ -\x50]|\x52[ -\x51]|\x53[ -\x52]|\x54[ -\x53]|\x55[ -\x54]|\x56[ -\x55]|\x57[ -\x56]|\x58[ -\x57]|\x59[ -\x58]|\x5a[ -\x59]|\x5b[ -\x5a]|\x5c[ -\x5b]|\x5d[ -\x5c]|\x5e[ -\x5d]|\x5f[ -\x5e]|\x60[ -\x5f]|\x61[ -\x60]|\x62[ -\x61]|\x63[ -\x62]|\x64[ -\x63]|\x65[ -\x64]|\x66[ -\x65]|\x67[ -\x66]|\x68[ -\x67]|\x69[ -\x68]|\x6a[ -\x69]|\x6b[ -\x6a]|\x6c[ -\x6b]|\x6d[ -\x6c]|\x6e[ -\x6d]|\x6f[ -\x6e]|\x70[ -\x6f]|\x71[ -\x70]|\x72[ -\x71]|\x73[ -\x72]|\x74[ -\x73]|\x75[ -\x74]|\x76[ -\x75]|\x77[ -\x76]|\x78[ -\x77]|\x79[ -\x78]|\x7a[ -\x79]|\x7b[ -\x7a]|\x7c[ -\x7b]|\x7d[ -\x7c]|\x7e[ -\x7d]|\x7f[ -\x7e]
Try it online!
A (better) alternative is to enumerate the ascii characters in reverse order and use the ^ and $ anchors to assert there is nothing else unmatched. This should work for any string length:
^\x7f?\x7e?\x7d?\x7c?\x7b?z?y?x?w?v?u?t?s?r?q?p?o?n?m?l?k?j?i?h?g?f?e?d?c?b?a?`?\x5f?\x5e?\x5d?\x5c?\x5b?Z?Y?X?W?V?U?T?S?R?Q?P?O?N?M?L?K?J?I?H?G?F?E?D?C?B?A?#?\x3f?\x3e?\x3d?\x3c?\x3b?\x3a?9?8?7?6?5?4?3?2?1?0?\x2f?\x2e?\x2d?\x2c?\x2b?\x2a?\x29?\x28?\x27?\x26?\x25?\x24?\x23?\x22?\x21?\x20?$
Try it online!
You may replace ? with * if you want to allow duplicate characters.
ps: some people can come up with absurdly long regexes when they aren't the right tool for the job: to parse email, html or the present question.

What is the regular expression that generates the language where every odd position in the string is an a?

What is the regular expression that generates the language where every odd position in the string is an a? (Please answer with the shortest possible regex: minimal parentheses, no spaces and any piped strings in alphabetical order!)
I assume I'm working with only a's and b's.
(a(a|b))+ would only cover even strings: a(a|b), a(a|b)a(a|b), etc.
How do I also cover the case that the string is odd? ex: a(a|b)a
Note: not using programming syntax
Edit: some valid strings would be: a, aa, aaa, aaaa, aaaaa, ab, aba, abab, ababa, etc.
EDIT: Solution
My instructor gave the answer (aa|ab)*. This is incorrect because it misses case(s), for example "a".
I think this suits your requirement:
^a(.a)*.?$
Position 1 must be "a": ^a
Repetitions of any character + a, making a sequence where odds are "a"'s: (.a)*
Allowing for a termination not ending in "a", ex abab: .?$
You can check it here: regex101
^(a.)*a?$
Allows empty values ("")
From start to end of line (^...$)
Every odd place (1,3,5,...) is an a followed by any letter/number
There may or may not be an a in the end
One sign shorter thay Jorge's answer, but allows empty values
See regex101 example here
I think this might help you
Case 1: even length strings (1(0+1))*
Case 2: odd length strings 1((0+1)1)*
Finally the answer is Case 1 + Case 2

Regex expression not behaving as expected in matlab

In matlab I have a string like :
y = '[3-G]]3|25+3|[3-G]4|25+4|G5|25+5|F'
Then I have a variable named intHit, which I need to return a cell array, containing an int if it is followed by a sign. So if we define it as:
intHit = regexp(y,'(\d*)([+-])','Match');
It returns something like:
intHit =
1×5 cell array
'3-' '25+' '3-' '25+' '25+'
HOWEVER, sometimes my intHit call, depending on the input of y returns minus(-) signs without an integer in front of it. I think my regex expression is faulty. Can someone help me format this so it will only return an integer followed by a plus(+) or minus(-) sign. So always something like the example above. Thanks in advance.
Try this instead:
intHit = regexp(y,'(\d+)([+-])','Match');
^--- that's the change
I think you had the wrong quantifier. * will match 0 or more times consecutively (which means it could match lone pluses and minuses), while + will match 1 or more times consecutively.
Also, if you're not capturing tokens, you can simplify your match expression to just '\d+[+-]'.

Regular expression to validate sum of numerics

I want to validate the user input,
it should accept,
1+2
1.2+56+3.5
it should not accept any alphabets, special characters other than . and +
and mainly it should not accept ++ and ..
please help me with regular expression.
This should work:
var regex = /^[0-9]+(\.[0-9]+)?(\+[0-9]+(\.[0-9]+)?)*$/;
"1+2".match(regex); // not null
"1.2+56+3.5".match(regex); // not null
"1++2".match(regex); // null
"1..2".match(regex); // null
online: http://regex101.com/r/zJ6tP7/1
Something like this should suffice
^([+]?\d+(\.\d+)?)*$
http://regex101.com/r/qE2kW1/2
Source: Validate mathematical expressions using regular expression?
Note that I'm assuming it should not accept .+ or +. as well. I'm not assuming that you require checking for multiple decimals prior to an addition, meaning this will accept 3.4.5 I'm also assuming you want it to start and end with numbers, so .5 and 4+ will fail.
(\d*[\.\+])*(\d)*
This takes any amount of number values, followed by a . or a +, any number of times, followed by any other number value.
To avoid things like 3.4.5 you'll likely need to use some sort of lookaround.
EDIT: Forgot to format regular expression.

Create Regex pattern for calculator

I am trying to create a calculator,where operands are words.It can repeat any number of times.
e.g. EmpName+xyz or EmpName or x+rr+fff.
It should reject such pattern e.g.
EmpName+
I created a regular expression:
(?m)(?<Operand>^[a-z].*?)(?<Operator>[+*])
On this output:
1) a + b
2) ab+dddd
3) ab*fffff*ggggg
4) dfg+fg4444+fgf4
5) xxxxx
But it only targets 1,2,3,4 and up to only first operator. Output in regex 2.05.
"Operand: [ab]"
"Operator:[+]"
I am using regex builder 2.05 to test my regex. How i can repeat this pattern any number of times? Thanks in advance.
This would typically be expressed as
operand followed by (operator operand) one or more times
that is
(?m)<Operand>([+*]<Operator>)*
Yes i need parantheses as well as divide,percentage,minus sign also.
Then I suggest considering using a real parser. The language of balanced parentheses is not regular.