Home > Blockchain >  Replacing exact words or phrases
Replacing exact words or phrases

Time:10-22

I am writing a text based adventure game in a batch file.

Long story short, I want the program to convert a sentence the user types into the game from the first person into the second person, by simply replacing singular pronouns such as 'I' with 'You.'

So a person says: I search inside the box. The program says: You search inside the box.

For this I'm using this script where 'choice' contains the user's entry.

set choice=%choice:i=you%
set choice=%choice:we=you%
set choice=%choice:us=you%
set choice=%choice:my=your%
set choice=%choice:myself=yourself%
set choice=%choice:ourselves=yourselves%
set choice=%choice:am=are% 
set choice=%choice:I'm=you're% 
set choice=%choice:I am=you are% 

However, every instance of 'I' is replaced. So when you type: I search inside the box. You get: You search younsyoude the box.

How do I tell the program to only replace an exact phrase (including spaces.) I want to try and avoid using powershell if at all possible. Otherwise, I'm not opposed to ideas.

CodePudding user response:

Something like this:

@echo off

set /p "line=Enter sentence: "
for %%f in (
    "i:you"
    "we:you"
    "us:you"
    "my:your"
    "myself:yourself"
    "ourselves:yourselves"
    "am:are"
    "I'm:you're"
) do for /F "tokens=1,* delims=:" %%g in ("%%~f") do for %%i in (%line%) do if /i "%%~g" == "%%~i" call set line=%%line:%%~i=%%~h%%
echo %line%

So, the better method would be to include setlocal delayedexpansion instead of call set, but there is a chance the sentence might contain ! which will be removed from the line if delayedexpansion is used.

Should the line contain any special characters after a word to replace, then you either need to add them to the list, i.e. i?:you? which will match if input is something like Where am I? which effectively will be replaced with Where are you? etc.

The second option is to temporarily replace any special characters during the match phase, and re-add them once done.

PS!! You do not need to add I am:You are to the list as I am already matching standalone I with You and am with are.

CodePudding user response:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory and filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q74160637.txt"

SET "userprompt=What now"

:again

SET "response="
SET /p "response=%userprompt% ? "
IF NOT DEFINED response ECHO Goodbye&GOTO :eof
SET "reply="
FOR %%w IN (%response%) DO (
 SET "subsword="
 FOR /f "usebackqtokens=1*delims=:" %%o IN ("%filename1%") DO IF /i "%%o"=="%%w" SET "subsword=%%p"
 IF DEFINED subsword (SET "reply=!reply! !subsword!") ELSE (SET "reply=!reply! %%w")
)
SET "reply=%reply:~1%"
ECHO %reply%
SET "userprompt=and then"
GOTO again

GOTO :EOF

Note that if the filename does not contain separators like spaces, then both usebackq and the quotes around %filename1% can be omitted.

Where the file q74160637.txt contains

i:you
we:you
us:you
my:your
myself:yourself
ourselves:yourselves
am:are
I'm:you're
I am:you are

Note that response is set to nothing directly before the set /p. I Enter alone is pushed in response to the prompt, then the variable will remain unchanged, so clearing it means it will remain undefined. Consequently, the fact that it's undefined after the set /p means that the user has just pushed Enter to exit the program.

The meat of the matter here is that the %%w loop processes each word in the response as the default separator is space. The routine then reads each line from the file q74160637.txt, and attempts to match the word in %%w to the first "token" in the line read. The tokens are strings delimited by any of the characters defind as delims (in this case, :); the first token from the line myself:yourself is thus myself and the remainder of the line (token *) is yourself. The first token is assigned to %%o and the second to %%p (next alphabetically). See the documentation at for /? from the prompt - or many thousand examples here at SO.

Since subsword is cleared before the file is checked, if it is defined after the for %%o then a substitute word was found, so add it to the reply string, otherwise add the word read from the response.

The concatenation will have a leading space. This can be removed by the set...~1.. hieroglyphics. See set /? from the paste of the inevitable many thousand examples here at SO.

Note the use of delayedexpansion, which needs to be used as the strings reply and subsword are being altered within a (parenthesised code block) - see Stephan's DELAYEDEXPANSION link or - you guessed it - many thousand examples here at SO.

Note that this will only replace words - replacing phrases would be a tad more difficult, but could be done.

  • Related