finding the string between two sets of alternate strings with overlapping occurence

Viewed 66

I have a number of strings look like:

str1="Quantity and price: 120 units;the total amount:12000.00"
str2="Quantity:100, amount:10000.00"
str3="Quantity:100, price: 10000 USD"
str4="Parcel A: Quantity:100, amount:$10000.00,Parcel B: Quantity:90, amount:$9000.00"
strlist=[str1,str2,str3,str4]

I want to match tha amount $12000, $10000, 10000 in the first 3 strings and both $10000 and $9000.00 in the last string. However, in the first string there are both "price" and "amount". I thought by using "|" regex would search from left to right, so I want regex to look "amount" first, if it is not presented then look for "price". I tried the following code:

amount_p = re.compile(r'(?:amount|price):(.*?)(?:USD|\.00)') 
for i in strlist:
    amount=re.findall(amount_p,i)
    print(amount)
[' 120 units;the total amount:$12000']
['10000']
[' 10000 ']
['$10000', '$9000']

Somehow the regex ignored "amount" and only looked for "price" in the first string. Then I tried following:

amount_p = re.compile(r'.*(?:amount|price):(.*?)(?:USD|\.00)') 

which gives me

['12000']
['10000']
[' 10000 ']
['$9000']

In this case, regex only matched $9000 in the last string and ignored $10000. So my question is what is the function of .* at the begining and is there anyway to solve my problem? Looking for numbers doesn't work because in my actual data there are many other numbers in one text. Thank you all in advance!!!!

2 Answers

With the first statement:

amount_p = re.compile(r'(?:amount|price):(.*?)(?:USD|\.00)')

You didn't group the string properly as you meant to do (i believe you meant to group by ':'), so you still had you string existing as one. You were only able to get your figures out in str2 and str3 because '.USD' and '.00' came to your rescue.

With the second statement:

amount_p = re.compile(r'.*(?:amount|price):(.*?)(?:USD|\.00)')

You were able to split your strings properly using the ':'. As such, str1 one then looks like:

Portion1: "Quantity and price" and Portion2: "120 units;the total amount:12000.00"

and so you were able to extract your values. You may view it as doing something like this:

strlist=[str1.split(';')[1],str2,str3,str4]

which when combined with your first pattern gives the same result as the second

Reference: https://www.tutorialspoint.com/python/python_reg_expressions.htm

You may use

re.findall(r'(?:price|amount):\s*\$?(\d+)(?:\.\d+|\s*USD)', text)

See the regex demo

Details

  • (?:price|amount) - price or amount
  • : - a colon
  • \s* - 0+ whitespaces
  • \$? - an optional dollar sign
  • (\d+) - Group 1: one or more digits
  • (?:\.\d+|\s*USD) -- a non-capturing group matching either . and 1+ digits or 0+ whitespaces and then USD substring.
Related