0

I have a string that looks like

no-mac4-two-git5a0r-m0-18md12b....

I'm trying to match it as /^\D+\d+\D+\d\D\d\D+\d+\D+(\d+)/ but it is not correct. Can I get some help with this? I only need to match this part of the string although there is more to it which is why I'm using the "+" at the end.

Further explanation:

These strings are part of a path name. I am trying to retrieve some paths based off whether they match the regex. All the paths have a string with the exact same pattern and format as I showed above. I am not able to successfully return any paths with the way I was matching it though.

  • 2
    What is your desired output? – Bijan Sep 03 '19 at 20:19
  • Can you explain your string further? What is the pattern of the string in terms of letters (upper or lower case), numbers, dashes, etc.? – dvo Sep 03 '19 at 20:19
  • 1
    You did not match the last 3 parts https://regex101.com/r/JU1nJa/1/ Why not use a pattern like `^[a-z0-9]+(?:-[a-z0-9]+)*` https://regex101.com/r/gdoklm/1 – The fourth bird Sep 03 '19 at 20:20
  • @dvo that is the exact pattern of all the strings. The letters may vary and the numbers but all of them have the exact same amount of letters in the same place with the same amount of numbers in the same place and same dashes in the same place. So right now, I'm looking for an exact matching for the string above. – programminglearner Sep 03 '19 at 20:23
  • @Thefourthbird I tried that but it did not work. – programminglearner Sep 03 '19 at 20:25
  • 1
    Which one did not work? The first or the second? Are you only matching characters a-z, `-` and 0-9? Because `\D` matches not a digit and is a broad match. – The fourth bird Sep 03 '19 at 20:26
  • @Thefourthbird I tried "^[a-z0-9]+(?:-[a-z0-9]+)*". Also, I just edited my post to elaborate a bit further on the issue. Edit: testing it out with the site link you provided right now. – programminglearner Sep 03 '19 at 20:27
  • @Thefourthbird The first one is not working either. I also added a "+" to the end because there are more letters and dashes that follow in the string but that did not work. – programminglearner Sep 03 '19 at 20:30
  • 1
    Does your match start at the start of the string? Else try omitting the leading `^` – The fourth bird Sep 03 '19 at 20:32
  • @Thefourthbird yes, it does start at the start. – programminglearner Sep 03 '19 at 20:32
  • Show the code, you may be using the regex in a wrong way. – Wiktor Stribiżew Sep 03 '19 at 20:35
  • 1
    What are the ellipsis (`...`) for -- can you show the whole, actual string? (Along with your actual code as Wiktor asked.) Do you literally just need to "_match_" it (to know that it's there) or do you need to extract stuff from it, like that last digit? (btw, the string you show has `b` last, not the digit(s).) – zdim Sep 03 '19 at 21:00
  • 1
    `** Grp 0 - ( pos 0 : len 25 ) no-mac4-two-git5a0r-m0-18 ** Grp 1 - ( pos 23 : len 2 ) 18` is exactly what matches. What is your question ? –  Sep 03 '19 at 21:05
  • 2
    "_it is not correct_" -- how/why is it not correct? The regex you show on that string you show captures number `18`. What do you want to capture? – zdim Sep 03 '19 at 21:05
  • You might as well use this `/^\D+(?:\d+\D+)+(\d+)/` you don't get any difference any other way. If you have a certain number of _yes/no_ pairs of which to validate, use a quantifier `/^\D+(?:\d+\D+){4}(\d+)/` –  Sep 03 '19 at 21:13
  • @WiktorStribiżew I don't think so because I used it for other patterns of strings, as well. I was able to get the regex right and it worked fine. So the problem seems to be me incorrectly matching. My code is about 500 lines – programminglearner Sep 03 '19 at 21:42
  • @sln `/^\D+(?:\d+\D+)+(\d+)/` worked! thank you!!! – programminglearner Sep 03 '19 at 21:44
  • You're quite welcome –  Sep 03 '19 at 22:10
  • So, you basically want to match the last chunk of digits in a string? `/\d+(?=\D*$)/` or `/\d+(?!.*\d)/`. – Wiktor Stribiżew Sep 04 '19 at 00:01
  • 1
    Lets basically benchmark it `Regex1: ^\D+(?:\d+\D+)+(\d+) Completed iterations: 50 / 50 ( x 1000 ) Elapsed Time: 0.37 s, 374.02 ms, 374018 µs Matches per sec: 133,683 Regex2: \d+(?=\D*$) Completed iterations: 50 / 50 ( x 1000 ) Elapsed Time: 0.43 s, 429.60 ms, 429597 µs Matches per sec: 116,388 Regex3: \d+(?!.*\d) Completed iterations: 50 / 50 ( x 1000 ) Elapsed Time: 0.45 s, 452.38 ms, 452375 µs Matches per sec: 110,527` The farther out you go, the worse it gets for the assertions, by exponentially.. –  Sep 04 '19 at 19:06
  • 1
    It is for this performance reason and some others, I'm opening it back up. –  Sep 04 '19 at 19:10
  • 1
    I agree that it could qualify as a dupe of matching the last number in a string. @sln Out of curiosity, why reopen the question without providing one of the patterns as an answer? Do you agree reclosing the question instead? – The fourth bird Sep 09 '19 at 16:17
  • @Thefourthbird - `I agree that it could qualify as a dupe of matching the last number in a string` Really ? How do you know that ? And if so, what makes you think any dup is correct in advising a method as listed ? I assert that you cannot advise a solution that says to skip to the end of a string. There is no such thing brother .. –  Sep 09 '19 at 19:15
  • @sfr So, `/(\d+)(?=\D*$)/` will [also work](https://ideone.com/mpNqu8), right? It is clear then you need to match the last number in a string and [this](https://stackoverflow.com/questions/5320525/regular-expression-to-match-last-number-in-a-string) is a valid dupe reason. Please consider removing this post as I cannot reclose it. – Wiktor Stribiżew Sep 17 '19 at 11:42
  • 1
    Possible duplicate of [Regular expression to match last number in a string](https://stackoverflow.com/questions/5320525/regular-expression-to-match-last-number-in-a-string) – tripleee Sep 20 '19 at 10:53
  • I disagree that this is a duplicate of the proposed dup-target. The OP has said they want to match the entire string up to what's described in the question, not just the last digit (as is the case in the proposed dup-target). Unfortunately, the OP hasn't said what "there is more to it" actually consists of. We have to *assume* the OP saying `/^\D+(?:\d+\D+)+(\d+)/` worked indicates they want to match the entire string up to the last digit, but even that is uncertain, because we don't know what's in the final portion of the string and we're not actually told there are no more digits. – Makyen Sep 27 '19 at 07:25

1 Answers1

0

You say /^\D+(?:\d+\D+)+(\d+)/ worked for you so your question is about matching the last 1+ digit chunk in the string.

The answers are here:

(\d+)(?!.*\d)
(\d+)\D*\z
.*(?:\D|^)(\d+)

Proof:

if ("no-mac4-two-git5a0r-m0-18md12b...." =~ /(\d+)(?=\D*$)/) {
    print "$1";
}
# => 12
if ("no-mac4-two-git5a0r-m0-18md12b...." =~ /(\d+)\D*\z/) {
    print "$1\n";
}
# => 12
if ("no-mac4-two-git5a0r-m0-18md12b...." =~ /.*(?:\D|^)(\d+)/) {
    print "$1";
}
# => 12
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563