Note: The commands below focus just on the -replace
operation; simply substituting the RHS of one of these operations for the RHS of the -replace
operation in the code in the question is enough - although adding the -File
switch is advisable to ensure that no accidental attempt to rename directories is made.[1]
To insert literally after the 7th character:
PS> '123456_9999999999999_DocName.pdf' -replace '(?<=^.{7})', 'DocType_'
123456_DocType_9999999999999_DocName.pdf
Note: As filimonic's helpful answer shows, you don't need a regex in this simple case; using the [string]
type's .Insert()
method is both simpler and faster.
More flexibly, to insert after the first _
in the name:
PS> '123456_9999999999999_DocName.pdf' -replace '(?<=^[^_]+_)', 'DocType_'
123456_DocType_9999999999999_DocName.pdf
Note:
(?<=...)
is a positive look-behind assertion that matches the position of the subexpression represented by ...
here - from the beginning (^
), either the first 7 characters (.{7}
), or a nonempty run (+
) of characters other than _
([^_]
) followed by a _
.
The replacement string ('DocType_'
) is therefore inserted into (a copy of) the original string at that position.
The look-behind approach obviates the need to refer to part of what was captured by the regex in the replacement operand, such as the use of $&
in Wiktor's answer.
- Note: While this approach is convenient and works well here, it has its pitfalls, because an anchored-to-the-start (
^
) subexpression inside a look-behind assertion doesn't always behave the same as outside of one - see this post.
See this answer for an overview of PowerShell's -replace
operator.
[1] If the -replace
operation turns out to be a no-op (if the regex doesn't match, the input string is returned as-is), trying to rename a directory to its existing name will actually generate an error, unlike with files - see GitHub issue #14903.