request : find and replace using PowerShell (regex)

hi, sorry i not native english speaker,

i have this example of a part of a js file, let said this text below is in random line, and lines total usually are 100 to 150:

{
    ID: Player,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}

i like to find and replace only the Atk of the player to 999 using PowerShell batchfile,

the code i want is find:

    ID: Player,
    Lvl: /*ignore this text*/,
    Atk: *,

then replace it with:

    ID: Player,
    Lvl: /*ignore this text*/,
    Atk: 999,

because of this specific case, i am sorry if i asked the complete program,

i hope somebody can create for me or give me a clue how to create it,

thanks for read, have a nice day.

Hopefully this example will help you.

$text = @'
{
    ID: Player,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}
'@

$text -replace '(?<=Atk: )\d{2,3}','999'

Output

{
    ID: Player,
    Lvl: 10,
    Atk: 999,
    Def: 50,
}

Here is how it would look reading from a file.

$text = get-content c:\path\to\jsfile.js -raw

$text -replace '(?<=Atk: )\d{2,3}','999'

thank you for the reply Doug Maurer,

i do not test it the code yet, because I don’t see the “keyword” of “Player” in your code, i assume another data who have “keyword” “Atk” will change to 999 too if i using your code, and i want to edit “Atk” only in “ID: Player” stats,

thank you again for your reply, i really appreciate it

 

OK, perhaps this example will help more.

$text = @'
{
    ID: NotPlayer,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}
{
    ID: Player,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}
'@

$text -replace '(?s)(?<=ID: Player.*Atk: )\d{2,3}','999'

Output

{
    ID: NotPlayer,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}
{
    ID: Player,
    Lvl: 10,
    Atk: 999,
    Def: 50,
}

thanks again for the reply,

i test your code like this :

(Get-Content c:\test.txt) -replace ‘(?s)(?<=ID: Player.*Atk: )\d{2,3}’,‘999’ | Set-Content c:\tast.txt

to this (input, the test.txt file):

{
    ID: NotPlayer,
    Lvl: 10,
    Atk: 30,
    Def: 50,
}
{
    ID: Player,
    Lvl: 10,
    Atk: 40,
    Def: 50,
}

and the result (tast.txt, new file created) is same with test.txt,

i am sorry for newbie question, but what did i wrong?

As I stated in my original reply, use -Raw on Get-Content. Let me know if that helps

thank you, now it works,

this the code :

(Get-Content c:\test.txt -raw) -replace ‘(?s)(?<=ID: Player.*Atk: )\d{2,3}’,‘999’ | Set-Content c:\tast.txt

now i just need to study what '(?s)(?<= and \d{2,3} do,

thank you again!!!

Good deal. Hopefully this helps with your research.

Single line mode
(?s) for “single line mode” makes the dot match all characters, including line breaks.
This is why it required -Raw, making the entire text one line instead of multi line. It would’ve been much harder to achieve your desired result going line by line.

Positive Lookbehind
(?<=…)
Ensures that the given pattern will match, ending at the current position in the expression. The pattern must have a fixed width. Does not consume any characters.
This is what allowed it to only match when the specified text that came before.

\d matches any numeric character. {2,3} turned that into “match 2 or 3 numeric characters only”

thank you again for the reply.

for the (?s) and \d{2,3} is understandable, but for <=… i google it, and found nothing about it,

do you have a link about it? I quite embarrass always asking the newbie questions

Check out the RexEgg page about lookarounds: Lookahead and Lookbehind Tutorial—Tips &Tricks
and the regular-expression.info page: Regex Tutorial - Lookahead and Lookbehind Zero-Length Assertions

thank you grokkit, now i more (not fully, but more) understand about it