37

I need to add a number to a backreference while doing a replace operation.

e.g. I am rewriting a URL

www.site.com/doc.asp?doc=321&language=1

to

www.site.com/headline/100321.article

I'm doing a simple replace, but I need to add 100,000 to the doc ID. What I have below works so far without adding anything.

s/.*doc=(\d+).*/www.site.com\/headline\/$1.article/g;

How can I add 100,000 to $1?

Note, you can't just add 100 before the number because the doc ID might be > 999.

2
  • 2
    I managed to do a simple math expression by using the 'e' flag. s/.*doc=(\d+).*/$1+100000/e but that way it only returns the number and not the 'wrapping' URL. I need to concatenate this with the rest of the string. Commented Mar 9, 2011 at 11:26
  • +1 Thanks for this question. Helped me do something similar with the Linux program rename. Commented Nov 29, 2011 at 16:05

3 Answers 3

40

using Perl:

s/.*doc=(\d+).*/"www.site.com\/headline\/".($1+100000).".article"/e;

as you've done with e flag, the right part becomes now an expression. so you have to wrap the non-capture part as strings.

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

3 Comments

Do you happen to know if this works in the .Net regex parser?
@Kevin, no it does not. The ($1+100000) part is being evaluated by Perl, regex has nothing to do with this. But, it looks like you're already using Perl, no?
I was using Perl to get the regex correct before "implanting" it into a c# program! I think I'm going to end up doing it programmatically in the end, but I'm pretty sure this answer will help a lot of folks with a similar problem.
8

That's not possible in regex. Regex only matches patterns, it doesn't do arithmetic.

The best you can do is something verbose like:

match       replace

(\d{6,})    $1
(\d{5})     1$1
(\d{4})     10$1
(\d{3})     100$1
(\d{2})     1000$1
(\d)        10000$1

4 Comments

Would it be possible to create a regex that does do arithmetic though? Like an extremely complicated one? I know it would be far from the most efficient way to do it, but it would still have value as a technical exercise. That's actually how I found this page (through a related Google search): because I was curious if this was possible or if anyone had done it.
@flarn2006, no, like I said, regex only matches patterns, it doesn't do arithmetic. Regex will only tell you "yes, the text matches the pattern you provided (or no, it didn't)", nothing else.
What about making a regex that matches an arithmetic statement that's correct? Like "45+6=51" would match, but "38+16=4" would not. Would that be possible in theory?
@flarn2006 It's possible, but only via a more complex flavor of regex, or with a loop, and even then using a loop means you have to convert to unary meaning adding 100000 would mean you'd need to store a 100kb string
4

If you only have a few articles you could just brute force it

...doc=322 -> www.site.com/headline/100322.article
...doc=323 -> www.site.com/headline/100323.article
...doc=324 -> www.site.com/headline/100324.article
...etc

Math in regex, you see it here first.

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.