2

Given this single-line input:

City, Country|[email protected]|john-doe-1234567|https://www.example.com/john-doe-site|john|doe|

I want to know if this is possible to grab the last two | characters - ie the pipes surrounding doe, but without matching doe.

I know the regex code to get all the | with (\n?)\|.

I've tried (?<=[a-z])\|\w+\| and (?<![a-z])\|\w+\|. The positive lookbehind and negative lookbehind both were closest I got but didn't hit the mark... In VSCode, I get something like this:

enter image description here

Currently, can not figure out a way where I get just the last two | characters without also returning a word that comes in-between the |.

4
  • "how would you do that?" match all the |, capture the last 3 one by one. If you specify three | at the end of your regex, your "match all the |" part of the regex won't be able to match those, and will let your capturing group match and capture them (that said you "match all the |" regex doesn't seem correct, but i'm confident you'll find a solution by yourself) Commented Dec 11, 2021 at 19:01
  • Yeah... not really unfortunately. That's why I'm asking. Commented Dec 11, 2021 at 23:40
  • 1
    \|(?=(?:[^|]*\|)?[^|]*$) Commented Dec 14, 2021 at 22:43
  • @RyszardCzech Thanks so much! I don't think I would've figured it out! I'm going to have to break it down later to learn more about it! Commented Dec 15, 2021 at 6:09

2 Answers 2

1

Use a look ahead for the rest of input being 0-n non-pipes then an optional pipe (which includes being nothing - ie will match the last char):

\|(?=[^|]*\|?$)

See live demo.

Regex breakdown:

  • \| a (literal) pipe
  • (?=...) a look ahead, which asserts that what follows matches ...
  • [^|]* any number (including none) of chars not a pipe (note how the pipe char doesn't need escaping when in a character class, as is the case for most chars that would otherwise have special meaning)
  • \|? an optional pipe char
  • $ end of input
Sign up to request clarification or add additional context in comments.

Comments

0

Use

\|(?=(?:[^|]*\|)?[^|]*$)

See regex proof.

BREAKDOWN

--------------------------------------------------------------------------------
  \|                       '|'
--------------------------------------------------------------------------------
  (?=                      look ahead to see if there is:
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (optional
                             (matching the most amount possible)):
--------------------------------------------------------------------------------
      [^|]*                    any character except: '|' (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      \|                       '|'
--------------------------------------------------------------------------------
    )?                       end of grouping
--------------------------------------------------------------------------------
    [^|]*                    any character except: '|' (0 or more
                             times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    $                        before an optional \n, and the end of
                             the string
--------------------------------------------------------------------------------
  )                        end of look-ahead

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.