Hello!

So I’m brand new to perchance, so please make sure to explain things to me very thoroughly.

I’m trying to make a random genotype generator, that then looks at what was generated and replaces it with words for the phenotype.

I’ve got it figured out for the most part, but what baffles me is that stringing .replace together for multiple instances (maybe I’m doing it wrong), does not have each replace function look at the entire string.

I’ve done quite a bit of googling, and found a few things similar to my issue, but could not understand them enough to implement the fixes.

As a word/name example: I have outputs of “Mary” and “Marybeth”. I want Mary replaced with “Anne”, and Marybeth replaced to “Susan”.

However, what I’m essentially getting is Anne and Annebeth, with no reference to Susan whatsoever (but in my actual use-case, a number tacked on the end of a string of letters).

Is there a way to force the replace function to only replace characters if the entire bit in quotations matches, and not replace partial matches?

  • wthit56@lemmy.world
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 months ago

    I see you’ve found the regex solution. Alternatively you can use .replaceAll("Marybeth", "Susan").replaceAll("Mary", "Anne") to replace all instances.

    To explain why you got things like Annebeth… the key is also the order you’re doing these replacements. If you do them in the other order, they will be processed in the other order. The first replace is done, which returns a new string. Then the next replace is done on that new string, and returns a new final string.

    Step 1:
    "Marybeth Susan Mary Anne".replaceAll("Marybeth", "Susan")
     ^^^^^^^^
     Susan
    Step 2:
    "Susan Susan Mary Anne".replaceAll("Mary", "Anne")
                      ^^^^
                      Anne
    Final:
    "Susan Susan Anne Anne"
    

    Versus with the same replaces happening in a different order:

    Step 1:
    "Marybeth Susan Mary Anne".replaceAll("Mary", "Anne")
     ^^^^
     Anne
    Step 2:
    "Annebeth Susan Mary Anne".replaceAll("Marybeth", "Susan")
    * no instances of Marybeth
    Final:
    "Annebeth Susan Mary Anne"
    

    This problem can also happen with regex, like .replaceAll(/Mary/, "Anne") will do the exact same find and replace.

    If these names are always on their own separate like then your regex of /^Mary$/ will find that okay. But if it’s inside a line of normal text, it won’t find it at all.

    What you can do with regex is check for word boundaries. As in, on the left there’s not a word character… letter, number, (or underscore?). And on the right there is a word character. Or on the left there is a word character and on the right there isn’t a word character. This can be used to check for complete words and not match partial words.

    A word boundary with a “b” for boundary: \b. So instead you could use the regex /\bMary\b/ and it would find “Mary” but not find the beginning of “Marybeth”. Because the point after “Mary” isn’t a word boundary. There’s a word character on the left “y” and also a word character on the right “b”. So it won’t match, because it’s not a complete “word.”

    That’s how to search/replace a particular word and make sure it’s not inside another word.

    Also, the code .replace(/^Mary$/, "Anne") will still only find one instance and stop, just as before. So you can use .replaceAll() instead. Or add a “flag” to the regex to tell it to find as many instances as it can. The flag you want is the “global” flag, and the flag indicator is “g” for global. You add the flag after the ending /. So the code would become .replace(/^Mary$/g, "Anne") and now it would find all the instances of Mary. (In this case on its own line.)