regexp: refer to alternation of groups












0















I want to replace such string



let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`


you can get my intention from this workable code



s = s.replace(/(=|~)('|")(.*?)1/g, `<code>$2$3</code>`)
.replace(/(=|~)(.*?)('|")1/g, `<code>$2$3</code>`)


now s is



<code>"blah</code>
<code>'blah"</code>
<code>'blah'</code>
<code>blah"</code>
<code>blah"</code>
<code>blah'</code>


My question is how to achieve that within one replace function, like:



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>${$3 || $5}${$4 || $6}</code>`)
// extra line to push annoying scroll bar down


this code doesn't work ofc. more specifically, how to refer to ... oh my god I just realized that I can just refer the whole group like below to satisfy my requirement



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>$2</code>`)


However, since the question is half done, and I still curious about how to refer to $3 or $5, string way, not the callback way.



Or I've stepped into an impasse.










share|improve this question























  • I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

    – CertainPerformance
    Jan 2 at 1:46













  • @CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

    – nichijou
    Jan 2 at 2:05


















0















I want to replace such string



let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`


you can get my intention from this workable code



s = s.replace(/(=|~)('|")(.*?)1/g, `<code>$2$3</code>`)
.replace(/(=|~)(.*?)('|")1/g, `<code>$2$3</code>`)


now s is



<code>"blah</code>
<code>'blah"</code>
<code>'blah'</code>
<code>blah"</code>
<code>blah"</code>
<code>blah'</code>


My question is how to achieve that within one replace function, like:



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>${$3 || $5}${$4 || $6}</code>`)
// extra line to push annoying scroll bar down


this code doesn't work ofc. more specifically, how to refer to ... oh my god I just realized that I can just refer the whole group like below to satisfy my requirement



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>$2</code>`)


However, since the question is half done, and I still curious about how to refer to $3 or $5, string way, not the callback way.



Or I've stepped into an impasse.










share|improve this question























  • I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

    – CertainPerformance
    Jan 2 at 1:46













  • @CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

    – nichijou
    Jan 2 at 2:05
















0












0








0








I want to replace such string



let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`


you can get my intention from this workable code



s = s.replace(/(=|~)('|")(.*?)1/g, `<code>$2$3</code>`)
.replace(/(=|~)(.*?)('|")1/g, `<code>$2$3</code>`)


now s is



<code>"blah</code>
<code>'blah"</code>
<code>'blah'</code>
<code>blah"</code>
<code>blah"</code>
<code>blah'</code>


My question is how to achieve that within one replace function, like:



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>${$3 || $5}${$4 || $6}</code>`)
// extra line to push annoying scroll bar down


this code doesn't work ofc. more specifically, how to refer to ... oh my god I just realized that I can just refer the whole group like below to satisfy my requirement



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>$2</code>`)


However, since the question is half done, and I still curious about how to refer to $3 or $5, string way, not the callback way.



Or I've stepped into an impasse.










share|improve this question














I want to replace such string



let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`


you can get my intention from this workable code



s = s.replace(/(=|~)('|")(.*?)1/g, `<code>$2$3</code>`)
.replace(/(=|~)(.*?)('|")1/g, `<code>$2$3</code>`)


now s is



<code>"blah</code>
<code>'blah"</code>
<code>'blah'</code>
<code>blah"</code>
<code>blah"</code>
<code>blah'</code>


My question is how to achieve that within one replace function, like:



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>${$3 || $5}${$4 || $6}</code>`)
// extra line to push annoying scroll bar down


this code doesn't work ofc. more specifically, how to refer to ... oh my god I just realized that I can just refer the whole group like below to satisfy my requirement



s = s.replace(/(=|~)(('|")(.*?)|(.*?)('|"))1/g, `<code>$2</code>`)


However, since the question is half done, and I still curious about how to refer to $3 or $5, string way, not the callback way.



Or I've stepped into an impasse.







javascript regex






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 2 at 1:42









nichijounichijou

825




825













  • I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

    – CertainPerformance
    Jan 2 at 1:46













  • @CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

    – nichijou
    Jan 2 at 2:05





















  • I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

    – CertainPerformance
    Jan 2 at 1:46













  • @CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

    – nichijou
    Jan 2 at 2:05



















I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

– CertainPerformance
Jan 2 at 1:46







I don't understand the question - it sounds like your code works already? Can you edit out the question that you solved and elaborate on what the real problem is? $3 will refer to the 3rd capture group, similarly with $5

– CertainPerformance
Jan 2 at 1:46















@CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

– nichijou
Jan 2 at 2:05







@CertainPerformance $3 and $5 are in an alternation group, so they are mutually exclusive. I want to refer to the one matched.

– nichijou
Jan 2 at 2:05














1 Answer
1






active

oldest

votes


















1














A capture group that doesn't get matched, when included in the second callback to a .replace, will result in an empty string. So, if group 3 and 5 are mutually exclusive, and you want to refer to either group 3 or group 5, whichever was matched, you can just write $3$5 - the one which was not matched will simply result in the empty string (so it won't cause any issues in the result).






let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`;


const replaced = s.replace(
/(=|~)(('|")(.*?)|(.*?)('|"))1/g,
`<code>$2 and group 3 or 5 is [$3$5]</code>`
);
console.log(replaced);





Note that in this case it would make more sense to use non-capturing groups rather than capturing groups when you don't want to save that resulting group for something, and it would make more sense to use a character set than alternating inside a group:






let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`;


const replaced = s.replace(
/([=~])((['"]).*?|(.*?)['"])1/g,
`<code>$2 and group 3 or 4 is [$3$4]</code>`
);
console.log(replaced);





Note that groups 3 and 5 in your original code refer to the quote (in the first alternation) and the text (in the second alternation), which seems a bit odd. Perhaps you wanted the text in both:






let s = `
~"blah~
~'blah"~
~'blah'~
~blah"~
=blah"=
=blah'=`;


const replaced = s.replace(
/([=~])(['"](.*?)|(.*?)['"])1/g,
`<code>$2 and group 3 or 4 is [$3$4]</code>`
);
console.log(replaced);








share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000337%2fregexp-refer-to-alternation-of-groups%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    A capture group that doesn't get matched, when included in the second callback to a .replace, will result in an empty string. So, if group 3 and 5 are mutually exclusive, and you want to refer to either group 3 or group 5, whichever was matched, you can just write $3$5 - the one which was not matched will simply result in the empty string (so it won't cause any issues in the result).






    let s = `
    ~"blah~
    ~'blah"~
    ~'blah'~
    ~blah"~
    =blah"=
    =blah'=`;


    const replaced = s.replace(
    /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
    `<code>$2 and group 3 or 5 is [$3$5]</code>`
    );
    console.log(replaced);





    Note that in this case it would make more sense to use non-capturing groups rather than capturing groups when you don't want to save that resulting group for something, and it would make more sense to use a character set than alternating inside a group:






    let s = `
    ~"blah~
    ~'blah"~
    ~'blah'~
    ~blah"~
    =blah"=
    =blah'=`;


    const replaced = s.replace(
    /([=~])((['"]).*?|(.*?)['"])1/g,
    `<code>$2 and group 3 or 4 is [$3$4]</code>`
    );
    console.log(replaced);





    Note that groups 3 and 5 in your original code refer to the quote (in the first alternation) and the text (in the second alternation), which seems a bit odd. Perhaps you wanted the text in both:






    let s = `
    ~"blah~
    ~'blah"~
    ~'blah'~
    ~blah"~
    =blah"=
    =blah'=`;


    const replaced = s.replace(
    /([=~])(['"](.*?)|(.*?)['"])1/g,
    `<code>$2 and group 3 or 4 is [$3$4]</code>`
    );
    console.log(replaced);








    share|improve this answer




























      1














      A capture group that doesn't get matched, when included in the second callback to a .replace, will result in an empty string. So, if group 3 and 5 are mutually exclusive, and you want to refer to either group 3 or group 5, whichever was matched, you can just write $3$5 - the one which was not matched will simply result in the empty string (so it won't cause any issues in the result).






      let s = `
      ~"blah~
      ~'blah"~
      ~'blah'~
      ~blah"~
      =blah"=
      =blah'=`;


      const replaced = s.replace(
      /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
      `<code>$2 and group 3 or 5 is [$3$5]</code>`
      );
      console.log(replaced);





      Note that in this case it would make more sense to use non-capturing groups rather than capturing groups when you don't want to save that resulting group for something, and it would make more sense to use a character set than alternating inside a group:






      let s = `
      ~"blah~
      ~'blah"~
      ~'blah'~
      ~blah"~
      =blah"=
      =blah'=`;


      const replaced = s.replace(
      /([=~])((['"]).*?|(.*?)['"])1/g,
      `<code>$2 and group 3 or 4 is [$3$4]</code>`
      );
      console.log(replaced);





      Note that groups 3 and 5 in your original code refer to the quote (in the first alternation) and the text (in the second alternation), which seems a bit odd. Perhaps you wanted the text in both:






      let s = `
      ~"blah~
      ~'blah"~
      ~'blah'~
      ~blah"~
      =blah"=
      =blah'=`;


      const replaced = s.replace(
      /([=~])(['"](.*?)|(.*?)['"])1/g,
      `<code>$2 and group 3 or 4 is [$3$4]</code>`
      );
      console.log(replaced);








      share|improve this answer


























        1












        1








        1







        A capture group that doesn't get matched, when included in the second callback to a .replace, will result in an empty string. So, if group 3 and 5 are mutually exclusive, and you want to refer to either group 3 or group 5, whichever was matched, you can just write $3$5 - the one which was not matched will simply result in the empty string (so it won't cause any issues in the result).






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
        `<code>$2 and group 3 or 5 is [$3$5]</code>`
        );
        console.log(replaced);





        Note that in this case it would make more sense to use non-capturing groups rather than capturing groups when you don't want to save that resulting group for something, and it would make more sense to use a character set than alternating inside a group:






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])((['"]).*?|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);





        Note that groups 3 and 5 in your original code refer to the quote (in the first alternation) and the text (in the second alternation), which seems a bit odd. Perhaps you wanted the text in both:






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])(['"](.*?)|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);








        share|improve this answer













        A capture group that doesn't get matched, when included in the second callback to a .replace, will result in an empty string. So, if group 3 and 5 are mutually exclusive, and you want to refer to either group 3 or group 5, whichever was matched, you can just write $3$5 - the one which was not matched will simply result in the empty string (so it won't cause any issues in the result).






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
        `<code>$2 and group 3 or 5 is [$3$5]</code>`
        );
        console.log(replaced);





        Note that in this case it would make more sense to use non-capturing groups rather than capturing groups when you don't want to save that resulting group for something, and it would make more sense to use a character set than alternating inside a group:






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])((['"]).*?|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);





        Note that groups 3 and 5 in your original code refer to the quote (in the first alternation) and the text (in the second alternation), which seems a bit odd. Perhaps you wanted the text in both:






        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])(['"](.*?)|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);








        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
        `<code>$2 and group 3 or 5 is [$3$5]</code>`
        );
        console.log(replaced);





        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /(=|~)(('|")(.*?)|(.*?)('|"))1/g,
        `<code>$2 and group 3 or 5 is [$3$5]</code>`
        );
        console.log(replaced);





        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])((['"]).*?|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);





        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])((['"]).*?|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);





        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])(['"](.*?)|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);





        let s = `
        ~"blah~
        ~'blah"~
        ~'blah'~
        ~blah"~
        =blah"=
        =blah'=`;


        const replaced = s.replace(
        /([=~])(['"](.*?)|(.*?)['"])1/g,
        `<code>$2 and group 3 or 4 is [$3$4]</code>`
        );
        console.log(replaced);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 2 at 2:14









        CertainPerformanceCertainPerformance

        93.6k165484




        93.6k165484
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54000337%2fregexp-refer-to-alternation-of-groups%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            Npm cannot find a required file even through it is in the searched directory