Can Regex return the starting position of a match?

I have written a simple script to match book titles that contain a 4-digit year field enclosed in parenthesis, and additionally, that the 4-digit year begins with ‘1’ or ‘2’:

$test = @(Book1 (1995), Book2 (2001), Book3 (2004) ...)

Foreach ($t in $test) {
    $t -match '^.+\((1|2)\d{3}\)'
}

The above seems to work fine, but I need to get an integer value that tells me starting where in the string the match occurred – so I can extract it. Can PS/Regex return such a value? Would be grateful for any tips or guidance. Thanks in advance.

 

Why not use named captures?

$Test = "Book1 (1995)", "Book2 (2001)", "Book3 (2004)"
$Test | Foreach-Object {
  $_ -match "\((?&ltYear&gt[0-9]{4})\)$" | Out-Null
  $matches.Year
}

Kris.

Remark: I replaced “<” and “>” by the HTML codes so it would show up in the preformatted code, so don’t just copy and paste.

Have to share it as a gist.

Hi JS,

Thanks, I was considering that but it’s really just three lines of code.

Kris.

As for …

I was considering that but it's really just three lines of code.

… why, is the number of lines it takes of value as long as it gets you your results?

One can cramp any code, but, once has to consider readability, maintainability, consideration of those whose will follow or use you stuff, etc…

Also, this…

$test = @(Book1 (1995), Book2 (2001), Book3 (2004) ...)

… is not a properly formatted array. So, I am wondering how you say…

The above seems to work fine

… when running, by itself, will just generate errors

 $test = @(Book1 (1995), Book2 (2001), Book3 (2004))

Book1 : The term 'Book1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was 
included, verify that the path is correct and try again.

So, cramping the use case, could just be something like this, in a one liner, no additional steps required.

 @('Book1 (1995)', 'Book2 (2001)', 'Book3 (2004)') | 
 ForEach-Object{[regex]::Matches($test,'\((?<Year>[0-9]{4})\)$').Value}

# Results

(2004)
(2004)
(2004)

Thank you everyone for your very creative, informative and educational insights.

Yes, I am guilty of taking short cuts in describing/stating my problem. My sincere apologies.

When I listed the array $test = @(Book1 …) I was trying to be sufficiently brief to give the reader a good idea of what the data looks like, with the 3 dots to mean “and so on”. Yes, next time I will be more precise.

I am very thankful you have all taken the efforts to share your PowerShell knowledge; for a beginner like me, these replies have been the best source of learning PowerShell.

No worries.
It happens, and we all had to start from somewhere, and trip over our own feet many times and that will never change. It’s part of the learning process.