1

I am trying to replace the last number of each match in between parenthesis.

so if I had cos(3 * 3)

before this regex

result = result.replace(/\d+(?:\.\d+)?/g, x => `${x}deg`)

would turn cos(3 * 3) into cos(3deg * 3deg)

I need only the last number to be changed to deg

So if I had cos(3 * 3) + cos(3 * 2) it would be cos(3 * 3deg) + cos(3 * 2deg)

What regular expression magic could I use to do this.

1
  • try \d+(?=\s?\)) This will match any numeral before closing brackets. Commented Feb 10, 2022 at 20:42

3 Answers 3

1

... /\((?<first>.*?)(?<last>[\d.]+)\)/g ...

// see ... [https://regex101.com/r/aDXe3B/1]
const regXLastNumberWithinParentheses =
  /\((?<first>.*?)(?<last>[\d.]+)\)/g;

const sampleData =
`cos(3 * 3) + cos(3 * 24.5), cos(2 * 3) + cos(3 * 2.4)
cos(3 * 3.4) + cos(3 * 45), cos(4 * 2) + cos(3 * 245)`;

console.log(
  sampleData.replace(
    regXLastNumberWithinParentheses,
    (match, first, last) => `(${ first }${ last }deg)`
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

1st Edit

Any idea why in this (3*(2+1+1)-12/5) is coming out as (3*(2+1+1deg)-12/5) it needs to match the last number regardless so it would be (3 *(2+1+1deg) - 23/5deg) – Nik Hendricks

@NikHendricks ... "Any idea why ...?" Yes of cause. Though the above regex matches anything and a final number in between parentheses, it does so just for un-nested parentheses (any nested structures can not be recognized). ... Question: Could one assume that the passed string does always feature validly nested parentheses? If yes, it leads to more straightforward regex replacement patterns because a regex then does not need to also validate the parentheses syntax. – Peter Seliger

... regex update ... /(?<![.\d])(?<number>\d*(?:\.\d+)?)\s*\)/g

// see ... [https://regex101.com/r/aDXe3B/2]
const regXLastNumberBeforeClosingParenthesis =
  /(?<![.\d])(?<number>\d*(?:\.\d+)?)\s*\)/g;

const sampleData =
`cos(3 * 3) + cos(3 * 24.5  ), cos(2 * 3  ) + cos(3 * 2.4)
cos(3 * 3.4) + cos(3 * 45  ), cos(4 * 2  ) + cos(3 * 245)

(3 * (2 + 1 + 1) - 23/5)`;

console.log(
  sampleData.replace(
    regXLastNumberBeforeClosingParenthesis,
    (match, number) => `${ number }deg)`
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

2nd Edit

for me the desired result for 3*(1571-sin(1 * 12)) would be 3*(1571deg -sin(1 * 12deg)) the last or only occurrence of a number is replaced with xdeg – Nik Hendricks

... regex update ... /(?<number>(?<!\.)\d+(?:\.\d+)?|(?<![\d.])(?:\.\d+)(?!\.))(?<termination>\s*[-+)])/g

// see ... [https://regex101.com/r/aDXe3B/3]
const regXValidNumberBeforePlusOrMinusOrClosingParenthesis =
  /(?<number>(?<!\.)\d+(?:\.\d+)?|(?<![\d.])(?:\.\d+)(?!\.))(?<termination>\s*[-+)])/g;

const sampleData =
`cos(3 * 3) + cos(3 * 24.5  ), cos(2 * 3  ) + cos(3 * .2.4)
cos(3 * 3.4) + cos(3 * 45  ), cos(4 * .24) + cos(3 * 245 )

(3 *(2 + 1 + 1) - 23/5 )

3 * (1571 - sin(12))`;

console.log(
  sampleData.replace(
    regXValidNumberBeforePlusOrMinusOrClosingParenthesis, '$1deg$2'
  )
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

Regarding the last iteration/edit ... in case number validation is not important (because the input is trusted), one of cause could achieve the same result with a less strict, thus simpler, regex which does not exclusively match valid numbers ... /(?<dotsAndDigits>[.\d]+)(?<termination>\s*[-+)])/g.

Sign up to request clarification or add additional context in comments.

4 Comments

Any idea why in this (3*(2+1+1)-12/5) is coming out as (3*(2+1+1deg)-12/5) it needs to match the last number regardless so it would be (3 *(2+1+1deg) - 23/5deg)
@NikHendricks ... "Any idea why ...?" Yes of cause. Though the above regex matches anything and a final number in between parentheses, it does so just for un-nested parentheses (any nested structures can nor be recognized). ... Question: Could one assume that the passed string does always feature validly nested parentheses? If yes, it leads to more straightforward regex replacement patterns because a regex then does not need to also validate the parentheses syntax.
Ah sorry I should have been more straightforward. Thanks a lot for your help. I'm just trying to convert an equation to use degrees for math.js. so all numbers that are either alone or the last number inside parenthesis will be changed. I appreciate the help have a nice day.
@NikHendricks ... there is a regex update which covers anything similar to the example of your first comment. It strictly validates the last number before a closing parenthesis, but allows whitespace in between the last number and the closing parenthesis.
1

You can simply use the closing braces to replace like this:

var result = "cos(3 * 3) + cos(3 * 245)"

result = result.replace(/(\d+)(\))/g,'$1deg)')

console.log(result)

Or just replace the last bracket.

var result = "cos(3 * 90) + sin(3 * 2)"

result = result.replace(/\)/g,'deg)')

console.log(result)

With Decimal add a character class using [] for . and digits

var result = "cos(3 * 3.4) + cos(3 * 245.5)"

result = result.replace(/([\d\.]+)(\))/g,'$1deg)')

console.log(result)

Any equation at the last number

var result = "3*(1571-sin(12))"

result = result.replace(/(\d\s{0,}\*+\d{0,})(.*\))/g,'$1$2deg')

console.log(result)

11 Comments

so will this replace each value with xdeg or just 1deg
yes any value xdeg will work
oh wow I never thought to replace just last ). Its amazing how just calming down and rethinking the whole thing can show there are much easier more logical options. Thank you.
is there any way your first regex could also match decimals.
Yes please refer the answer. Just made the change
|
1

The insertion position for deg is just a place between two defined Assertions.

(?<=\([^()]*\d)(?=[^()\d]*\))

https://regex101.com/r/sjw3CX/1

 (?<= \( [^()]* \d )           # Lookbehind open parenth up to last number
 (?= [^()\d]* \) )             # Lookahead no digits and must have a closing parenth

var input = " cos(3 * 3) + cos(3 * 2)"

var output = input.replace(/(?<=\([^()]*\d)(?=[^()\d]*\))/g,'deg')

console.log(output)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.