none
regex replace RRS feed

  • Question

  • Hi 

    I have a text file in variable $contact fill with string and lines like:

    Home Address: ******

    Tel no: *******

    Zipcode: *****

    my code

    $contact = Get-content c:\contact.txt 

    select-string $contact -pattern 'home address' | foreach-object {$_ -replace "\w\s\w\:\s "}

    how do i replace the string or word ***** which is unknown and behind "home address: " or "Tel no:" on the text file.



    • Edited by Noobpie Thursday, November 17, 2016 8:08 AM
    Thursday, November 17, 2016 7:31 AM

Answers

  • "Replace"?

    'Home Address: ******' -replace 'Home Address:.*', 'Home Address: new address'


    \_(ツ)_/

    • Marked as answer by Noobpie Thursday, November 17, 2016 9:19 AM
    Thursday, November 17, 2016 8:19 AM
  • Based on the fact that you said your variable is called $contact, I'm assuming you're using PowerShell.

    There's always a few ways to skin a cat and you could just parse it as a string using the IndexOf() and Substring() methods, but regex will definitely be faster and you have asked for regex so... Even within regex there are multiple ways of getting this done, mine is just an example.

    I'm assuming that, as per the example above, each of the entries are on a separate line. If they are, then your $contact variable will be a [string[]], which means that when we pipe it one line will be processed at a time (which is great!)

    So... let's move on to the regex:

    (?<=Tel no: ).*$

    Let's analyze this. Ignore for a while the positive lookbehind part of the regex (?<=Tel no: ), and focus on the capturing group that comes after, which is .*$. This will capture all characters in a string all the way to the end of the string.

    Great, on its own it's pretty useless here. However, when you put the positive lookbehind next to it (?<=Tel no: ), it basically translates into... capture any number of characters all the way to the end of the string, that are preceded by "Tel no: ". In other words, if the character being currently evaluated is not preceded by "Tel no: ", ignore it. If it is preceded by it, return it (and any characters that follow all the way of the end of the string), but do not include "Tel no: " in what you return.

    Obviously you can then use the same thing for the remaining strings...

    (?<=Home Address: ).*$

    (?<=Zipcode: ).*$

    ...

    etc

    Now, as for actually using this in PowerShell, you can just use the Replace() method of the regex class.

    Here's an example:

    $contact = @("Home Address: ******")
    $contact += "Tel no: *******"
    $contact += "Zipcode: *****"
    $contact | % {[regex]::Replace($_, "(?<=(Home Address|Tel no|Zipcode): ).*$", 'SOMETHING ELSE')}

    Now in my example I'm replacing all of the asterisks with "something else", you'll probably want to twink with that, but I'll leave you that to you :)


    • Edited by cogumel0 Thursday, November 17, 2016 8:29 AM
    • Marked as answer by Noobpie Thursday, November 17, 2016 9:19 AM
    Thursday, November 17, 2016 8:25 AM
  • This is really very simple:

    D:\scripts> $contact | %{$_ -replace 'Home Address:.*', 'Home Address: new address'}
    Home Address: new address
    Tel no: *******
    Zipcode: *****
    D:\scripts>

    One line not positive look behinds needed.


    \_(ツ)_/

    • Marked as answer by Noobpie Thursday, November 17, 2016 9:18 AM
    Thursday, November 17, 2016 8:31 AM

All replies

  • "Replace"?

    'Home Address: ******' -replace 'Home Address:.*', 'Home Address: new address'


    \_(ツ)_/

    • Marked as answer by Noobpie Thursday, November 17, 2016 9:19 AM
    Thursday, November 17, 2016 8:19 AM
  • Based on the fact that you said your variable is called $contact, I'm assuming you're using PowerShell.

    There's always a few ways to skin a cat and you could just parse it as a string using the IndexOf() and Substring() methods, but regex will definitely be faster and you have asked for regex so... Even within regex there are multiple ways of getting this done, mine is just an example.

    I'm assuming that, as per the example above, each of the entries are on a separate line. If they are, then your $contact variable will be a [string[]], which means that when we pipe it one line will be processed at a time (which is great!)

    So... let's move on to the regex:

    (?<=Tel no: ).*$

    Let's analyze this. Ignore for a while the positive lookbehind part of the regex (?<=Tel no: ), and focus on the capturing group that comes after, which is .*$. This will capture all characters in a string all the way to the end of the string.

    Great, on its own it's pretty useless here. However, when you put the positive lookbehind next to it (?<=Tel no: ), it basically translates into... capture any number of characters all the way to the end of the string, that are preceded by "Tel no: ". In other words, if the character being currently evaluated is not preceded by "Tel no: ", ignore it. If it is preceded by it, return it (and any characters that follow all the way of the end of the string), but do not include "Tel no: " in what you return.

    Obviously you can then use the same thing for the remaining strings...

    (?<=Home Address: ).*$

    (?<=Zipcode: ).*$

    ...

    etc

    Now, as for actually using this in PowerShell, you can just use the Replace() method of the regex class.

    Here's an example:

    $contact = @("Home Address: ******")
    $contact += "Tel no: *******"
    $contact += "Zipcode: *****"
    $contact | % {[regex]::Replace($_, "(?<=(Home Address|Tel no|Zipcode): ).*$", 'SOMETHING ELSE')}

    Now in my example I'm replacing all of the asterisks with "something else", you'll probably want to twink with that, but I'll leave you that to you :)


    • Edited by cogumel0 Thursday, November 17, 2016 8:29 AM
    • Marked as answer by Noobpie Thursday, November 17, 2016 9:19 AM
    Thursday, November 17, 2016 8:25 AM
  • Replace the old address(unknown) with a new address .


    Thursday, November 17, 2016 8:26 AM
  • "Replace"?

    'Home Address: ******' -replace 'Home Address:.*', 'Home Address: new address'


    \_(ツ)_/

    A positive lookbehind like in my example will perform a lot faster, and can also be done in one line if that's really something that important. Just sayin...

    Thursday, November 17, 2016 8:27 AM
  • This is really very simple:

    D:\scripts> $contact | %{$_ -replace 'Home Address:.*', 'Home Address: new address'}
    Home Address: new address
    Tel no: *******
    Zipcode: *****
    D:\scripts>

    One line not positive look behinds needed.


    \_(ツ)_/

    • Marked as answer by Noobpie Thursday, November 17, 2016 9:18 AM
    Thursday, November 17, 2016 8:31 AM
  • I didn't say they were needed. I said they're faster and more versatile.

    What if I wanted to replace all of the values (asterisks in this case) on all 3 fields with the string "unknown"? In your example you need 3 replaces, one per field being replaced because you're also replacing the part preceding the value itself...

    Thursday, November 17, 2016 8:36 AM
  • I tried all your solution

    Somehow it didn't change the line in the text file.

    Thursday, November 17, 2016 9:03 AM
  • $contact=gc C:\test.txt -Encoding UTF8

    please try before storing in to variable then you can replace hope it will work


    Prashant Dev Pandey LIVE IN YOUR OWN WAY pdppandey@hotmail.com 91-7795618301


    Thursday, November 17, 2016 9:29 AM
  • I tried all your solution

    Somehow it didn't change the line in the text file.

    None of the solutions presented sent the result to a text file. For that matter, it did not send it to a variable either. It just went straight to the console.
    Thursday, November 17, 2016 1:40 PM
  • I tried all your solution

    Somehow it didn't change the line in the text file.

    None of the solutions presented sent the result to a text file. For that matter, it did not send it to a variable either. It just went straight to the console.

    Yes - you have to write a script that uses the solution that also write the output to a file.

    \_(ツ)_/

    Thursday, November 17, 2016 5:11 PM
  • I didn't say they were needed. I said they're faster and more versatile.

    What if I wanted to replace all of the values (asterisks in this case) on all 3 fields with the string "unknown"? In your example you need 3 replaces, one per field being replaced because you're also replacing the part preceding the value itself...

    I didn't mean to imply you were wrong only that it was overkill and more confusing to a user who knows nothing about writing a script or using RegEx.

    I agree that, as a generalized solution yours is more flexible.  It is what I though of fist but chose the more explicit way as one that the user could include.

    As we can see know the user cannot even use the simplest of solutions.


    \_(ツ)_/

    Thursday, November 17, 2016 5:14 PM