0

I have a string that varies

BLUE ORIGIN             CONTACT:  MB

The first part is what varies, it's basically a customer name. So the number of characters and spaces will change.

I know I can use this and it will match what I need

$String = 'BLUE ORIGIN             CONTACT:  MB'
$string -match '(^\S+\s+\S+)(\s+)(CONTACT:)(\s+)(\S+)'
$Matches[1]

But if the string changes to something like this, with no spaces

CUSTOMERNAME            CONTACT:  MB

the -match is false.

How can I do a regex that grabs the first part of the string regardless of its length or characters?

Probably wasn't super clear. The Values I am after are

$Matches[1] - In the above would be BLUE ORIGIN

$Matches[3] - CONTACT:

$Matches[5] - MB

3
  • use [A-Za-z\s]+CONTACT:\s+\S+ Commented Dec 13, 2018 at 18:31
  • Is there a tab (\t) between ORIGIN and CONTACT ? Commented Dec 13, 2018 at 18:32
  • Is the data before CONTACT: guaranteed to be fixed-length? If so, do you know what that length is? Commented Dec 13, 2018 at 18:33

4 Answers 4

3

Regular expression engines usually support partial matches of strings. Don't try to match all the stuff before CONTACT:

$s = 'BLUE ORIGIN             CONTACT:  MB'
$s -match 'CONTACT:\s+(\S+)'
$Matches

Output:

Name                           Value
----                           -----
1                              MB
0                              CONTACT:  MB

(So you can just do $Matches[1] to get just the value you're after.)

If you need to break apart the whole line into several elements of data and not just this one, I don't think I'd use regular expressions. I'd look into developing a parser (syntactic analyzer). Doing that in PowerShell is probably ill-advised, though. Here are some .NET tools that might help with that.

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

Comments

2

You are IMO overcomplicating things.
With placing the parentheses for the capture groups you decide what to capture.

$String = 'BLUE ORIGIN             CONTACT:  MB'
$string -match '^(.*?)\s+(CONTACT:)\s+(\S+)' | Out-Null
$matches | ft -AutoSize

Name Value
---- -----
3    MB
2    CONTACT:
1    BLUE ORIGIN
0    BLUE ORIGIN             CONTACT:  MB

$string = "CUSTOMERNAME            CONTACT:  MB"
$string -match '^(.*?)\s*(CONTACT:)\s+(\S+)'|Out-Null
$matches | ft -AutoSize

Name Value
---- -----
3    MB
2    CONTACT:
1    CUSTOMERNAME
0    CUSTOMERNAME            CONTACT:  MB

1 Comment

Totally agree with just matching the strings you want to capture. This seems to best represent what the OP is asking for.
1

To make your regex work for both examples, you could change (^\S+\s+\S+) to (^\S+\s*\S+) making the whitespace \s* character match 0+ times instead of 1+ times.

(^\S+\s*\S+)(\s+)(CONTACT:)(\s+)(\S+)
.......^

Regex demo

You could omit the capturing group around (\s+) and just match \s+ if you are not referring to it anymore in your tool or code.

Comments

1

As per supplied data this will do job for you

[A-Za-z\s]+CONTACT:\s+\S+

Explanation

  • [A-Za-z\s]+ - Matches any alphabet or space one or more time.
  • CONTACT: - Matches CONTACT:.
  • \s+ - Matches one or more space character.
  • \S+ - Matches one or more non space character.

Demo

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.