1

I have the following:

$file_input = "cube1_server1_partial.xml"
$CUBEName = [io.path]::GetFileNameWithoutExtension($file_input).ToUpper() -replace "_partial" #strips extension from $file_input

This results in: cube1_server1.

Now I have other file names that came into light, such as:

cube1_server1_full.xml

I want a comprehensive replacement that doesn't necessarily have to hard code the suffix, so instead of -replace "_partial".

It should be something like -replace "_*" from the end of a string.

How can I have a comprehensive replace? maybe with regex?

4
  • 1
    So you want it to always remove the last _ and everything following it? Commented Aug 13, 2019 at 20:46
  • @MathiasR.Jessen correct. Commented Aug 13, 2019 at 20:46
  • 1
    $file_input -replace "_[^_]*$" will probably work for most cases. Commented Aug 13, 2019 at 20:50
  • @AdminOfThings that works too :D Commented Aug 13, 2019 at 20:55

3 Answers 3

3

this is yet another method to get the cleaned file name. [grin] however, if you have many such items to clean up, then the regex posted by Mathias R. Jessen is likely your best bet for speed.

what it does ...

  • split the string on the dot & save the parts into $Name & $Extension
  • split the $Name on _, skip the last item, rejoin the parts with _
  • join $WantedNamePart & $Extension with a .
  • display the results

the code ...

$FileName = 'cube1_server1_partial.xml'

$Name, $Extension = $FileName.Split('.')
$WantedNamePart = ($Name.Split('_') |
    Select-Object -SkipLast 1) -join '_'

$CleanedFileName = $WantedNamePart, $Extension -join '.'

$CleanedFileName

output ...

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

4 Comments

interesting, i didnt know you can do this: $Name, $Extension =
Multi-value assignments are fun, you can even swap two variable values in one statement $Name,$Extension = $Extension,$Name :D
@Cataster - yep, the multiple assignment thing is occasionally quite handy. [grin]
@MathiasR.Jessen thats like replacing a variable with temp, sweet!
3

Yet another solution:

PS> 'cube1_server1_partial.xml' -replace '(.*)_.*', '$1'
cube1_server1
  • (.*)_ greedily matches through the last _ and captures everything before it (.*) in the 1st capture group ((...)).

  • .* matches the rest, which ensures that the overall regex matches the entire input string.

  • Replacement string $1 then replaces the entire string with what the 1st capture group captured, which is everything before the last _.

See this answer for more information about the -replace operator.

Comments

2

If you want to remove the last _ and everything following it from a string, you have a couple of options.

Use String.LastIndexOf() and String.Remove():

$string = 'cube1_server1_partial'
$last_index = $string.LastIndexOf('_')
if($last_index -ne -1){
    $string = $string.Remove($last_index)
}

Or you could use the -replace regex operator with a more descriptive pattern:

$string = 'cube1_server1_partial'
$string -replace '(?<=.+)_[^_]*$'

The regex in the example above consists of:

(?<=  # positive look-behind assertion
  .+  # for 1 or more characters
)
_     # a literal underscore
[^_]* # any character that's NOT an underscore, 0 or more times
$     # followed by end of string

The look-behind ensure you don't end up with an empty string if the only _ occurs at position 0, eg. _partial would just return as is. For the non-regex method the equivalent would be to check for $last_index -gt 0 instead of -ne -1

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.