1

I am parsing a spice file with python which contains string math expressions and I am converting the text file to a python script.

An example of a math expressions in the file is:

expr = 'k1 + 4.35k + 3.69meg*(pow(2.4u, 2*km2))'

I would like to find all the scaling factors in the expression and convert them to their exponent values:

scaling_factors = {
    'g'  : 'e9',
    'meg': 'e6',
    'k'  : 'e3',
    'm'  : 'e-3',
    'u'  : 'e-6',
    'n'  : 'e-9',
}

my wanted output would be like:

converted_expr = 'k1 + 4.35e3 + 3.69e6*(pow(2.4e-6, 2*km2))'

I tried this:

digits_re = r"([0-9]*\.[0-9]+|[0-9]+)k"
sample = 'k1 + 4.3k'
print(re.sub(digits_re, digits_re.replace('k', 'e3'), sample))

output:

k1 + \\de3

but it doesn't work

darkoucha
  • 31
  • 5
  • Thanks for giving us a clear idea of what you want to achieve, but have you tried anything yourself? – rst-2cv May 28 '18 at 10:00
  • Have you at least tried to use `str.replace` ?? – Micolho May 28 '18 at 10:01
  • I started reading abour regular expressions very recently and so far my attempts have failed... I tried `import re sample = 'k1 + 4.35k + 3.69meg*(pow(2.4u, 2*km2))' print(re.findall("([0-9]*\.[0-9]+|[0-9]+)k", sample)) print(re.findall("([0-9]*\.[0-9]+|[0-9]+)meg", sample))` output ['4.35'] ['3.69'] – darkoucha May 28 '18 at 10:04
  • @IsslamAbdelhadi please add that attempt to your original post by editing it – rst-2cv May 28 '18 at 10:06

4 Answers4

3

Use a negative lookahead ((?<=...)) to make sure there's a number before the symbol(s), and a word boundary assertion (\b) to catch the "km2" case:

import re
expr = re.sub(r"(?<=\d)k\b", "e3", expr)

If you want to avoid doing this many times, there's a trick using a function as the replacement value:

def sn_replace(match):
    return scaling_factors[match.group(1)]

expr = re.sub(r"(?<=\d)(g|k|meg|m|u|n)\b", sn_replace, expr)

When the second argument to re.sub is a function, instead of replacing the match with a text, that function is called with the match object, and its return value is used as the replacement.

L3viathan
  • 26,748
  • 2
  • 58
  • 81
1

I am not sure if there are any libraries that do something like this.

As one of the comments suggest you can use str.replace, but you will have to write your own loop and If conditions as you only want to replace the letters if they are in the right place.

I know this isn't giving you the answer straight away but it can guide to the right path.

nzicher
  • 71
  • 8
0

Written a bit quickly so may not be perfect, but something like this?

import re
scaling_factors = {
    'g'  : 'e9',
    'meg': 'e6',
    'k'  : 'e3',
    'm'  : 'e-3',
    'u'  : 'e-6',
    'n'  : 'e-9',
}

expr = 'k1 + 4.35k + 3.69meg*(pow(2.4u, 2*km2))'

for k,v in scaling_factors.items():
    ptrn=re.compile('\d('+k+')\D')
    expr=ptrn.sub(v,expr)
print(expr)

output:

k1 + 4.3e3+ 3.6e6(pow(2.e-6 2*km2))
AlePorro
  • 111
  • 1
  • 11
-1

If you have the number as string you just need to replace:

for key in dictionary.iterkeys():
    address.replace(key, dictionary[key])

If you have the number in decimal values

from decimal import Decimal
'%.2E' % Decimal('40800000000.00000000000000')
# returns '4.08E+10'

Display a decimal in scientific notation

Nicolò Gasparini
  • 2,228
  • 2
  • 24
  • 53