Daniel Groves
Daniel Groves

Reputation: 472

Price Regex when mixed with other numbers

Trying to write some JavaScript regex to match the price when an option is selected from a dropdown. Example output: Acrylic Print 12 x 16 inch (£95)

I have the content in a variable (price) and I simply want to use match on this to select just the price. I currently have the following:

price = price.match(/[\d\.\d]+/i)

This gets the 12, not the 95.

Any help would be appreciated.

Cheers,

Dan.

Change 1

Trying HamZaDzCyberDeV' suggestion:

price.match(/(?<=£)\d+(?:\.\d+)?/)

Returns the following error.

Uncaught SyntaxError: Invalid regular expression: /(?<=�)d+(?:.d+)?/: Invalid group

Sorry, no idea what I'm doing when it comes to RegEx. Leaves me stumped every time.

Change 2

.match(/(?<=\(.)\d+\.*\d*(?=\))/i)

Error:

Uncaught SyntaxError: Invalid regular expression: /(?<=\(.)\d+\.*\d*(?=\))/: Invalid group

Upvotes: 0

Views: 342

Answers (2)

Ro Yo Mi
Ro Yo Mi

Reputation: 15010

Consider the following powershell example of a universal regex.

  • [(][^0-9.]?([.][0-9]{1,2}|[0-9]{1,}[.][0-9]{1,2}|[^.][0-9]{1,})[)] any single non numeric leading character will be ignored
  • [(][£$]([.][0-9]{1,2}|[0-9]{1,}[.][0-9]{1,2}|[^.][0-9]{1,})[)] must have a known currency symbol

Example

$Matches = @()
$String = 'Acrylic Print 12 x 16 inch (£95)  (£95.03)  (£95......00) (90)  (23.45) (£95.06) (.1) (.22)  (.) (£.24)  (£.)'
Write-Host start with 
write-host $String
Write-Host
Write-Host any valid decimal number inside parans
([regex]'[(][^0-9.]?([.][0-9]{1,2}|[0-9]{1,}[.][0-9]{1,2}|[^.][0-9]{1,})[)]').matches($String) | foreach {
    write-host "at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'"
    } # next match
Write-Host
Write-Host Only decimal number inside parans where the number is preceeded by a known symbol
 ([regex]'[(][£$]([.][0-9]{1,2}|[0-9]{1,}[.][0-9]{1,2}|[^.][0-9]{1,})[)]').matches($String) | foreach {
    write-host "at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'"
    } # next match

Yields

start with
Acrylic Print 12 x 16 inch (£95)  (£95.03)  (£95......00) (90)  (23.45) (£95.06) (.1) (.22)  (.) (£.24)  (£.)

any valid decimal number inside parans
at 29 = '95'
at 36 = '95.03'
at 59 = '90'
at 65 = '23.45'
at 74 = '95.06'
at 82 = '.1'
at 87 = '.22'
at 99 = '.24'

Only decimal number inside parans where the number is preceeded by a known symbol
at 29 = '95'
at 36 = '95.03'
at 74 = '95.06'
at 99 = '.24'

Summary

  • [(] matches the open parentheses in the input text
  • [£$] matches a single £ or $ symbol
  • [^0-9]? portion allows you to find any non number like the £ symbol. This may or may not actually exist in the source string
  • regex portion ([.][0-9]{1,2}|[0-9]{1,}[.][0-9]{1,2}|[^.][0-9]{1,}) locates and returns all valid numbers which may also contain a decimal point followed by 2 digits. This will not return just a "."
    • ( instructs regex to return anything found between this open parentheses and the close parentheses below
    • [.][0-9]{1,2} finds 1 or 2 numbers following a decimal point
    • | or
    • [0-9]{1,}[.][0-9]{1,2} 1 or more numbers before a decimal point followed by 1 or 2 numbers
    • | or
    • [^.][0-9]{1,} 1 or more numbers which are not do not follow a decimal point
    • ( close paran instructs regex to stop returning any additional matches. This close parentheses mates with the open parentheses above
  • [)] matches the close parentheses in the input text

Upvotes: 1

Walls
Walls

Reputation: 4010

You can try using (?<=\(.)\d+\.?\d*(?=\)). This will do a look ahead and a look behind to see if the digits are surrounded with (). You can see the testing of this here.

This is assuming the formatting is the same with no spaces inside the (). Breaking this down into smaller pieces you get:

  1. (?<=\(.) - a positive look behind of a ( followed by a char. This char is there to capture the sign used for the currency. If you have a specific currency marker being used, you can replace the . with the expected symbol. For now, any symbol between the ( and the start of the digits will work.
  2. \d+\.?\d* - the regex to find the digits. This finds (at least) one digit that maybe followed by a . and a second set of digits. This should handle capturing any change included in the price if it isn't just an even set "dollar" amount. Depending on how many digits can follow the decimal for whatever currency you use, you can change the second \d* to be \d{x,y} where the number of digits allowed in the decimal place is between x and y. So for 0 to 2 digits after the decimal you would use \d{0,2}.
  3. (?=\)) - a positive look ahead ensuring the regex is followed by a ).

These together help break the regex into smaller pieces so you can understand the different components and how they work, instead of just seeing a big long scary regex.

Upvotes: 0

Related Questions