tl;dr
Use -replace rather than -match to match and extract the parts of interest in a single operation, which requires you to:
design your regex to match the whole input string,
enclose the subexpressions that match the parts of interest in (…), i.e. capture groups
and refer to those parts in the substitution operand; $1 refers to what the first capture group captured, $2 the second, and so on.
Get-ChildItem |
Rename-Item -NewName { $_.Name -replace '^.*\b(\w\d+\w+\d+)\b.*(\.pdf)$', '$1$2' } -WhatIf
Note: As in your own code, the -WhatIf common parameter in the command above previews the operation. Remove -WhatIf and re-execute once you're sure the operation will do what you want.
Note that input files that don't match the regex are left untouched.
Read on for details.
As for:
I wonder if it's possible to do lazy matching using -match, .*? doesn't seem to do the trick.
The above uses \b (word-boundary assertions) as the more robust alternative to lazy matching, but .*? does work in principle, as the following simplified example shows:
# -> 'c12aa13.pdf'
'asdjlk-c12aa13-.pdf' -replace '^.*?(\w\d+\w+\d+).*(\.pdf)$', '$1$2'
That is, the ? after .* ensured that the c match was "given up" in order to match the following subexpression, (\w\d+\w+\d+), as early as possible - go to this regex101.com page and experiment with removing the ? to see the difference in behavior.
Explanation of the -replace technique and regex:
While you could follow the -match operation in your own attempt with subsequent extraction of the matched part(s) via the automatic $Matches variable, it's often easier to combine the two operations with the help of the -replace operator:
You just need to make sure that in order to return only the parts of interest, you must match the input string in full and then ignore the parts you don't care about, as shown in this simplified example:
# -> 'c12aa13.pdf'
'asdjlk-c12aa13-.pdf' -replace '^.*\b(\w\d+\w+\d+)\b.*(\.pdf)$', '$1$2'
For a more detailed explanation of the regex and the option to experiment with it, see this regex101.com page.
.*\b matches the prefix before the part of interest; \b makes sure that the following subexpression only matches at a word boundary (i.e. only at a character other than an alphanumeric one or _).
(\w\d+\w+\d+) matches the part of interest, wrapped in a capture group; since it is the 1st capture group in the regex, you can refer to what it captured as $1 in the replacement operand.
\b.*, at a word boundary, matches everything after up to the .pdf filename extension.
(\.pdf)$ matches filename extension .pdf at the end of the name and, as the 2nd capture group, can be referenced as $2 in the replacement operand.
Note that an alternative to operating on the full .Name value including the extension is to match against the .BaseName property only and append the .Extension property afterwards, along the lines of:
($_.BaseName -replace '…','…') + $_.Extension
$1$2 simply concatenates the 2 capture-group matches to output the desired name.
Note: Generally, use single-quoted strings for both the regex and the replacement operand, so that $ isn't accidentally interpreted by PowerShell beforehand.
For more information about -replace and the syntax of the replacement operand, see this answer.
example