Jump to content
jastey

Need help with REPLACE_TEXTUALLY (again)

Recommended Posts

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.

 

Share this post


Link to post

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.

Share this post


Link to post

@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.

Share this post


Link to post

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.

 

Share this post


Link to post
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 by Luke

Share this post


Link to post
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.....

Share this post


Link to post

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?

Share this post


Link to post

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.)

Share this post


Link to post

Turns out the exact same thing was explained to me in April 2018. In this thread.

I thank you for your patience.

 

Share this post


Link to post
Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...