lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Regexp Functions


From: Freeman Gilmore
Subject: Re: Regexp Functions
Date: Mon, 15 Jun 2020 20:57:15 -0400

Thank you Aaron.  :

In order to ask my question, not knowing how to ask, I simplified it
too much.   The one or both of the first two below  may work but i do
not know how to apply them.

Say I have "-y -ax3 +rx2 -stx2 t"    I wanted, if  "-" followed "x"
before a space, then replace the "x" with " -x" for each.    If I use
"(^-.*)x" "-y -ax3 +rx2 -stx2 t"  'pre 1 " -x" 'post) , from what I
have read, this would happen at the first "x" from the right.   So
that will not work.

My next step was to convert the string to a list of strings.  So if i
convert first, "-y -ax3 +rx2 -stx2 t" =>  ("-y" "-ax3" "+rx2" "-stx2"
"t") .   I would guess that one or both of the first two below could
be applied to the list of strings.    But i do not have a clue?
Starting with "-y -ax3 +rx2 -stx2 t" , ending with ("-y" "-a" "-x3"
"+rx2" "-st" "-x2" "t")

Thank you, ƒg


On Tue, Jun 9, 20'20 at 5:40 PM Aaron Hill <lilypond@hillvisions.com> wrote:
>
> On 2020-06-09 12:42 am, Freeman Gilmore wrote:
> > I do no tthink this is what i want.   Let me try again  Say you have
> > "Xsdfghjkl"     If "x" is the first
> >  character  then replace the "g" if it exist with "Y"   =>
> > "XsdYfhjkl"X
>
> /(^A.*)B/ is the general pattern:
>
>   (    )   Match the regex below and capture its match into backreference
> number 1.
>    ^       Assert position at the beginning of a line.
>     A      Match the character "A" literally.
>      .*    Match any single character that is NOT a line break character
>             between zero and unlimited times, as many times as possible,
>             giving back as needed (greedy).
>         B  Match the character "B" literally.
>
> Since "A" and "B" above are literals, they may be replaced with "X" and
> "g", respectively, if that is what you wanted.  Consider:
>
> ;;;;
> (regexp-substitute/global #f
>    "(^X.*)g"
>    "Xsdfghjkl"
>    'pre 1 "Y" 'post)
> ;;;;
>
> ====
> "XsdfYhjkl"
> ====
>
> Note that regular expressions can be a powerful tool [1], but they can
> also create more problems than they solve [2].
>
> [1]: https://xkcd.com/208/
> [2]: https://xkcd.com/1171/
>
> Your original problem involved conditionally replacing a substring based
> on whether the string starts with a particular prefix.  Consider:
>
> ;;;;
> ((lambda (s)
>      (if (string-prefix? "X" s)
>        (string-join (string-split s #\g) "Y")
>        s))
>     "Xsdfghjkl")
> ;;;;
>
> ====
> "XsdfYhjkl"
> ====
>
> In the above, we have separated the task into a few parts.  First is
> checking the prefix of the string, as the absence of the desired text
> means no work needs to be done.  When replacing, we use string-split and
> string-join to achieve our goal.  This works because we are looking for
> a single character to replace.
>
> A more general approach would need to use several of the string-* family
> of procedures:
>
> ;;;;
> (define (string-find-replace s1 s2 s3)
>    "Return the string @var{s1}, where all occurrences
> of @var{s2} are replaced by @var{s3}."
>    (let ((index (string-contains s1 s2)))
>      (if (number? index)
>        (string-append
>          (string-take s1 index)
>          s3
>          (string-find-replace
>            (string-drop s1 (+ index (string-length s2)))
>            s2
>            s3))
>        s1)))
> ((lambda (s)
>      (if (string-prefix? "XX" s)
>        (string-find-replace s "gg" "YY")
>        s))
>     "XXssddffgghhjjkkll")
> ;;;;
>
> ====
> "XXssddffYYhhjjkkll"
> ====
>
> Hopefully you can see that in this situation, regexp-substitute/global
> becomes the more succinct way to express things:
>
> ;;;;
> (regexp-substitute/global #f
>    "(^XX.*)gg"
>    "XXssddffgghhjjkkll"
>    'pre 1 "YY" 'post)
> ;;;;
>
> ====
> "XXssddffYYhhjjkkll"
> ====
>
>
> -- Aaron Hill



reply via email to

[Prev in Thread] Current Thread [Next in Thread]