Select-String works, need to convert to replace for CC number

This is my first post so I would like to say thanks for any insight up front.

I have some scripts I use for very specific purposes and do not have large experience.

I am trying to find and replace credit card numbers, except for last 4 digits.

The regex below works fine for my use as there are no spaces or other characters.

This Select-String returns exactly what I need when I view results in ISE:

Select-String Path\*txt -Pattern '[456][0-9]{15}'|ForEach-Object{$_ -Replace '[456][0-9]{11}' ,'XXXXXXXXXXXX'}

So the only way I’ve worked replace before is through Get-Child so:

Get-ChildItem Path\*txt |ForEach{(Get-Content -Path $_) -replace '[456][0-9]{11}' ,'XXXXXXXXXXX'| Set-Content $_}

To me it was obvious this wouldn’t work but I don’t know how to set the original pattern, the 15 followed by a replace of 11 literal.

In the last example, it does not know the 15 character limit and found and replaced a few system numbers that are long strings that might have a 4,5 or 6 in it. Like it put X’s in this 00780106260001002000. It is also replacing the correct strings in the standalone numbers but I feel something is missing here.

Could anyone offer a suggestion on this type of replace?


Not much in to regex, but I can suggest below,

Do a -match operation using regex, then check the length of the matched value (from $Matches), then replace.

You might start with learning more about regular expressions … Finding or Verifying Credit Card Numbers.
It depends pretty much how those credit card numbers are saved but a simple version could be something like this:

‘1234567890123456’ -replace ‘(\d{12})(\d{4})’ , ‘$1’

This -replace pattern is looking for 12 numbers followed by 4 numbers and it will replace all this with the found first group of numbers.

To expand a little on Olaf’s excellent suggestion, I typically prefer to use named match groups to make the methodology more clear when re-reading my own code: is nice for working out regex

I improved my regex to exclude digits before or after the match. Regex101 shows this works fine.

I used it on some sample data and it returned correct account numbers without including long system strings.

Getting to the replace part, I will look over the Olaf post and figure out how to swap all but the last 4 with X’s in this expression.


Will be later before I can try. Thank-you for the advice!


Hope this helps. I don’t think the forum is displaying your expression correctly. I got an error in regex101. \b is a word boundary. See the link.

PS C:\> '111 4111111111111111 1111' -replace '\b[4-6]\d{11}(\d{4})\b', 'XXXXXXXXXXXX$1'

111 XXXXXXXXXXXX1111 1111

Does it register a word boundary for a sequence of numbers?

He was doing negative lookarounds, but the forum formatting broke the regex by adding spaces in between characters needed for the lookaround definitions.

I think my example demonstrates that?

There a RegEx extension for VSCode.

RegExp Preview, I’ve used since it’s release, well, I have Sapien’s PSStudio and the Productivity pack, which include PowerRegEx, so, I actually spend more time with that one.

And there has been a RegEx addon for the ISE since circa 2014

ISERegex - ISE AddOn to simplify the work with Powershell and regular expression Did you ever worked with Powershell and regular expressions?Are you learning resistant againts regular expressions as I am?If all this applies to you ( or even if not) , then I have a cool solution for this problem. The ISERegex - ISE Add-On is a simple Addon for the Powershell I

The reg ex from js was exactly what I needed but I guess the other hints showed as well that I needed to break out a group.

I tested it last night and it works.

Nice to not have to do manually!

I will also look at match as well to see how that works.

ISERegex looks useful too so I grabbed it.


thanks all