jastey Posted April 18, 2019 Share Posted April 18, 2019 I need enlightment with regard to REPLACE_TEXTUALLY. I thought I know how to use it but it appears I really don't. With @K4thos' permission I am using the following code adapted from EET in my SoD Tweakpack which works fine, i.e. it gets patched accordingly: COPY_EXISTING ~BD6100.BCS~ ~override~ DECOMPILE_AND_PATCH BEGIN SPRINT textToReplace ~IncrementGlobal("bd_finale","bd6100",10)~ COUNT_REGEXP_INSTANCES ~%textToReplace%~ num_matches PATCH_IF (num_matches > 0) BEGIN REPLACE_TEXTUALLY ~%textToReplace%~ ~IncrementGlobal("bd_finale","bd6100",1)~ PATCH_PRINT ~Patching: %num_matches% matches found in %SOURCE_FILESPEC% for REPLACE_TEXTUALLY: %textToReplace%~ END ELSE BEGIN PATCH_WARN ~WARNING: could not find %textToReplace% in %SOURCE_FILESPEC%~ END END BUT_ONLY So, I'm a smart girl so I wanted to use this for another purpose. So I'm using this: COPY_EXISTING ~bd0120.BCS~ ~override~ DECOMPILE_AND_PATCH BEGIN SPRINT textToReplace ~InPartyAllowDead("imoen")~ COUNT_REGEXP_INSTANCES ~%textToReplace%~ num_matches PATCH_IF (num_matches > 0) BEGIN REPLACE_TEXTUALLY CASE_INSENSITIVE ~%textToReplace%~ ~\1 Global("C#st_ImoenInGroupKD","GLOBAL",0)~ PATCH_PRINT ~Patching: %num_matches% matches found in %SOURCE_FILESPEC% for REPLACE_TEXTUALLY: %textToReplace%~ END ELSE BEGIN PATCH_WARN ~WARNING: could not find %textToReplace% in %SOURCE_FILESPEC%~ END END BUT_ONLY and the install fails with the error message: Quote ERROR: [bd0120.BCS] -> [override] Patching Failed (COPY) (Failure("Str.replace: reference to unmatched group")) Stopping installation because of error. ERROR Installing [Imoen remains in the Group in Korlasz's Dungeon], rolling back to previous state Unable to Unlink [c#sodtweaks/backup/8/OTHER.8]: Unix.Unix_error(1, "unlink", "c#sodtweaks/backup/8/OTHER.8") [c#sodtweaks/backup/8/UNSETSTR.8] SET_STRING uninstall info not found Looking at what I did with REPLACE_TEXTUALLY elsewhere, I put the text into brackets and backslashs, and then it installs and patches fine: COPY_EXISTING ~BD6100.BCS~ ~override~ DECOMPILE_AND_PATCH BEGIN SPRINT textToReplace ~\(InPartyAllowDead("imoen")\)~ COUNT_REGEXP_INSTANCES ~%textToReplace%~ num_matches PATCH_IF (num_matches > 0) BEGIN REPLACE_TEXTUALLY CASE_INSENSITIVE ~%textToReplace%~ ~\1 Global("C#st_ImoenInGroupKD","GLOBAL",0)~ PATCH_PRINT ~Patching: %num_matches% matches found in %SOURCE_FILESPEC% for REPLACE_TEXTUALLY: %textToReplace%~ END ELSE BEGIN PATCH_WARN ~WARNING: could not find %textToReplace% in %SOURCE_FILESPEC%~ END END BUT_ONLY This leads to the following questions: 1. Why is k4thos' code working for bd6100.bcs (without bracktes and backslashes) but not in my case? 2. Why is the install failing at all and not just printing the ~WARNING: could not find %textToReplace% in %SOURCE_FILESPEC%~ line in my first case? My second question is relatedt to 1.2. Because, I want this to work on EET as well as SoD. So, I need the REPLACE_TEXTUALLY to consider both "imoen" and "imoen2" (case insensitive). I thought this is done by using "imoen[2]", but then I get the happy warning upon install: Quote WARNING: could not find \(InPartyAllowDead("imoen[2]")\) in bd0120.BCS So, here the warning actually works. Which leads me to my final, all defining question: How would the working, multiplatform code look like? If anyone could be of assistance, I'd be grateful. Quote Link to comment
CamDawg Posted April 18, 2019 Share Posted April 18, 2019 It's this bit here: ~%textToReplace%~ ~\1 Global("C#st_ImoenInGroupKD","GLOBAL",0)~ What WeiDU is saying is that you're trying to use a matched reference (the \1) without specifying a matched group. The various \1 \2 \3 etc. refer back to something you matched in the first half of the function, which you denote by wrapping it in \( and \). This is why your second example works, because you have a correctly delineated group. K4thos original code doesn't have a back reference like this so it doesn't need to be wrapped. It's failing outright because it's correctly finding matches but then failing at the actual REPLACE_TEXTUALLY because of the regexp error. For the Imoen stuff, use imoen2? The question mark means that the previous character or group--in this case, the number 2--can be matched 0 or 1 times. IOW this will match imoen or imoen2. Quote Link to comment
AL|EN Posted April 18, 2019 Share Posted April 18, 2019 @jasteyDo you use something like https://regexr.com/ for testing regex'es? Quote Link to comment
jastey Posted April 18, 2019 Author Share Posted April 18, 2019 @CamDawg Thank you very much! @AL|EN No. I am just using code snippets I have from elsewhere, I do not know regex coding. Quote Link to comment
AL|EN Posted April 18, 2019 Share Posted April 18, 2019 @jasteyThis site can explain it very, very well. There are explanation of each char when you hover you mouse. And it can display matching groups etc. I truly recommend it. Quote Link to comment
jastey Posted April 18, 2019 Author Share Posted April 18, 2019 @AL|EN Thank you, I thought you are referring to some tool or somesuch... A site with explanations is great. Quote Link to comment
Mike1072 Posted April 18, 2019 Share Posted April 18, 2019 There are many different implementations of regular expressions. The different implementations each have their own syntax and support for different operations. @AL|EN 's site may be helpful to learn some of the concepts, but keep in mind that, by comparison, WeiDU's regular expressions are relatively basic. They also employ a different syntax. This is the full explanation of regular expressions from the WeiDU readme: Quote A regular expression or regexp is "somewhat" like a DOS wildcard but not quite. The big difference is that if you would say * in DOS you say .* in regexp-land. Here’s a definition: The syntax for regular expressions is the same as in Gnu Emacs. The special characters are: $^.*+?[]\ The following constructs are recognized: . matches any character except newline * (postfix) matches the previous expression zero, one or several times + (postfix) matches the previous expression one or several times ? (postfix) matches the previous expression once or not at all [..] character set; ranges are denoted with -, as in [a-z]; an initial ^, as in [^0-9], complements the set ^ matches at beginning of line $ matches at end of line \| (infix) alternative between two expressions \(..\) grouping and naming of the enclosed expression \1 the text matched by the first \(...\) expression (\2 for the second expression, etc) \b matches word boundaries \ quotes special characters. So spe.* matches "sper01.itm" and "sper.eff" and "special". Hopefully this is understandable to most people. Quote Link to comment
Luke Posted April 19, 2019 Share Posted April 19, 2019 (edited) 17 hours ago, jastey said: I do not know regex coding. If you're curious and interested in knowing more about this, I can suggest you a textbook about Formal Languages and Compilers (Regular Expressions/Languages are the first family of formal languages). This is a textbook targeted to graduate (i.e., Master of Science) students in Computer Science and Engineering, so you may find it difficult to understand (in case you already have a solid background about the so called Theoretical Computer Science, then you should be ready to go....) Edited April 19, 2019 by Luke Quote Link to comment
jastey Posted April 20, 2019 Author Share Posted April 20, 2019 @Mike1072 Thank you! @Luke I'd be interested, but I am not sure I'd work my way through the book. Quote Link to comment
Luke Posted April 21, 2019 Share Posted April 21, 2019 On 4/20/2019 at 11:21 AM, jastey said: @Luke I'd be interested, but I am not sure I'd work my way through the book. I sent you a PM..... Quote Link to comment
jastey Posted December 31, 2019 Author Share Posted December 31, 2019 I have a problem with using REPLACE_REXTUALLY i am not sure the code is the problem. I am using this on SoD (flam12.bcs is present in the game): Spoiler COPY_EXISTING ~flam12.bcs~ ~override~ DECOMPILE_AND_PATCH BEGIN SPRINT textToReplace ~Global("Chapter","GLOBAL",7)~ COUNT_REGEXP_INSTANCES ~%textToReplace%~ num_matches PATCH_IF (num_matches > 0) BEGIN REPLACE_TEXTUALLY ~%textToReplace%~ ~\1 !Dead("Sarevok")~ PATCH_PRINT ~Patching: %num_matches% matches found in %SOURCE_FILESPEC% for REPLACE_TEXTUALLY: %textToReplace%~ END ELSE BEGIN PATCH_WARN ~WARNING: could not find %textToReplace% in %SOURCE_FILESPEC%~ END END BUT_ONLY And I get this error message: Spoiler ERROR: [flam12.bcs] -> [override] Patching Failed (COPY) (Failure("Str.replace: reference to unmatched group")) Could someone point me to what the problem is and what I need to do to patch the script? Quote Link to comment
Wisp Posted December 31, 2019 Share Posted December 31, 2019 It's the same as the last problem. Your REPLACE_TEXTUALLY ~%textToReplace%~ ~\1 !Dead("Sarevok")~ should presumably be REPLACE_TEXTUALLY ~\(%textToReplace%\)~ ~\1 !Dead("Sarevok")~ The back-reference (\1) is a reference to a matched group and as your code is currently written, there is no grouping (for which you use \(foo\). Also it's not necessary to have a newline before Sarevok's trigger: it will be discarded when your DECOMPILE_AND_PATCH closes and the script is compiled. (I think it helps readability to have it on the same line in cases like this.) Quote Link to comment
jastey Posted January 1, 2020 Author Share Posted January 1, 2020 Turns out the exact same thing was explained to me in April 2018. In this thread. I thank you for your patience. Quote Link to comment
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.