2

I really didn't want to ask this here as I'm sure this will get me downvoted, but I truly am stuck.

I have used multiple tools to test regex expressions but the syntax is very confusing.

What I have tried

I am going to be using javascript for this, I have the following string for example:

Product ID: 4381 - Fanta Berry cans 355ml x 24

This is a search result from an autocomplete dropdown, it will always have the format:

Product ID: product_id - Product Name

Now I need to get the product_id the number between the : and -

I have tried

/[\d]/g

But that simply selects all the numbers in the string.

I also tried:

[(:\b)-]

And that selects the : and - which are the characters between the number I want to get. But I can't seem to figure out the syntax to get the number between them. I feel like I'm very close but after hours of searching I can't seem to crack it, I know this isn't a place for people to do the work for you, but I assure you I have tried and am really at a loss! If anyone can tell me the little bit of syntax that's missing to get that number I would be very appreciative.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • 2
    You could try it like this `^[^:]+:[ \t]*(\d+)` using a capturing group https://regex101.com/r/yNY78Z/1 or more precise `^Product ID: (\d+) -` – The fourth bird Feb 03 '20 at 14:48
  • 1
    `str.match(/Product ID: (\d{1,4}) -/)[1]` – ASDFGerte Feb 03 '20 at 14:50
  • 1
    Any particular reason why you need to resort to parsing the string in orde to get the product id back? – Jens Stragier Feb 03 '20 at 14:51
  • 1
    You can match it with `/\d+/` fine, i.e. `string.match( /\d+/ )[ 0 ]`. (Also, remember that if you don't use the "global" flag it will only match the first result.) – Yannick K Feb 03 '20 at 14:57
  • 1
    PS: It may be "yet another simple regex problem", but your question includes signs of effort (attempts, which make me believe you actually spent time on this, before asking), so i don't see a reason to downvote. I only dislike it, when people's decision flowchart has the first arrow from "start" to "ask SO". Helping people, who are actually stuck, after trying, is exactly, what SO is for. – ASDFGerte Feb 03 '20 at 15:00
  • These are both great answers guys but they are selecting the words product ID: when I test them, I just need the numbers. It would appear the two answers below are brilliant as well. @YannickK That's a good idea why didn't I realise that! –  Feb 03 '20 at 15:00
  • @YannickK if you post your answer as an actual answer I will mark it as the correct one as it is the simplest and cleanest answer here in my opinion. If you don't want to submit it as an answer I will choose Pavel's answer instead. –  Feb 03 '20 at 15:04
  • @DinleyHob Sure, will do, then we can finalise the question. – Yannick K Feb 03 '20 at 15:07
  • 1
    In regex, capture groups (brackets) are used to get specific parts of a match as separate strings. Without a global flag, `String.prototype.match` returns the same structure as [exec](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec#Description). Therefore, these capture groups are accessible on the result with `[1]`, `[2]`, ... (depending on how many there are). If there is no match, the entire result will be `null` (a check for this helps prevent unhandled exceptions, when something goes wrong). – ASDFGerte Feb 03 '20 at 15:11
  • Oh very good to know, I have done some regex research, but I don't use it all that often. So this is the first time iv'e had to do it. –  Feb 03 '20 at 15:13
  • Many regex here have a full match which includes things like "Product ID: ", but only care about a capture group inside, which is only the digits (notice the brackets around the digit selectors, e.g. `(\d{1,4})` (one to four digits) or `(\d+)` (at least one digit, no upper limit). – ASDFGerte Feb 03 '20 at 15:13
  • Or perhaps split the string on a space and take the second part if `"Product ID:` is hardcoded and there are always digit following. – The fourth bird Feb 03 '20 at 15:15

3 Answers3

0

You can use a positive lookbehind:

(?<=(Product ID: ))(\d*)

Mind that this method is support by most, but not every browser.

PaulS
  • 850
  • 3
  • 17
  • 1
    I'm not sure why use a positive lookbehind here instead of simply a non-capturing group. Or even no group at all. – VLAZ Feb 03 '20 at 14:53
  • 1
    This worked well and supports in chrome which is the browser we use at work! Thank you. –  Feb 03 '20 at 15:01
0

Try specifying the product id prefix:

/Product ID: (\d+)/g

Here's full JavaScript code for you so that you don't get confused:

var str = "Product ID: 4381 - Fanta Berry cans 355ml x 24";
var ret = str.match(/Product ID: (\d+)/);
var product_id = ret[1];

console.log(product_id);
Pavel Lint
  • 3,252
  • 1
  • 18
  • 18
  • 1
    This also works perfectly well as well, however I am going to have to say Yannick K answer is the most simple and effective. Only she did not post an answer just a comment. –  Feb 03 '20 at 15:04
-1

You can use /\d+/ just fine:

const string = "Product ID: 4381 - Fanta Berry cans 355ml x 24";
const match = string.match( /\d+/ )[0];

console.log( match );

Just make sure to select the first element of the resulting array.

Also note that not using the global flag will have the RegEx only match the first result

Yannick K
  • 4,887
  • 3
  • 11
  • 21
  • 2
    Good show! You have imparted wisdom for which I shall be forever grateful. Regex is a nightmare in terms of syntax but like anything it'll just require some practice. Thank you again! –  Feb 03 '20 at 15:08