Javascript Regex Negative Lookahead match












0















I suck at regex. I have the following expression:



(?!.*")(Level)(s)([0-9])(?!.*")



I want to use this expression to replace all Level 2 to "Level 2" with queries. The problem is that this regex catches "Level 2(without closing "). I want to catch Level 2 only if it has to quotes before AND after the words.



What is the best approach to do that?










share|improve this question























  • Can you add some sample text and actual vs expected output with your current regex?

    – Pushpesh Kumar Rajwanshi
    Nov 20 '18 at 17:51











  • Try (?<=")levelsd+(?=")

    – K.Dᴀᴠɪs
    Nov 20 '18 at 17:52











  • I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

    – Filip
    Nov 20 '18 at 17:52











  • Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

    – Wiktor Stribiżew
    Nov 20 '18 at 17:52











  • @WiktorStribiżew not working. The callback is not called. Is this in the ES5?

    – Filip
    Nov 20 '18 at 17:56
















0















I suck at regex. I have the following expression:



(?!.*")(Level)(s)([0-9])(?!.*")



I want to use this expression to replace all Level 2 to "Level 2" with queries. The problem is that this regex catches "Level 2(without closing "). I want to catch Level 2 only if it has to quotes before AND after the words.



What is the best approach to do that?










share|improve this question























  • Can you add some sample text and actual vs expected output with your current regex?

    – Pushpesh Kumar Rajwanshi
    Nov 20 '18 at 17:51











  • Try (?<=")levelsd+(?=")

    – K.Dᴀᴠɪs
    Nov 20 '18 at 17:52











  • I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

    – Filip
    Nov 20 '18 at 17:52











  • Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

    – Wiktor Stribiżew
    Nov 20 '18 at 17:52











  • @WiktorStribiżew not working. The callback is not called. Is this in the ES5?

    – Filip
    Nov 20 '18 at 17:56














0












0








0








I suck at regex. I have the following expression:



(?!.*")(Level)(s)([0-9])(?!.*")



I want to use this expression to replace all Level 2 to "Level 2" with queries. The problem is that this regex catches "Level 2(without closing "). I want to catch Level 2 only if it has to quotes before AND after the words.



What is the best approach to do that?










share|improve this question














I suck at regex. I have the following expression:



(?!.*")(Level)(s)([0-9])(?!.*")



I want to use this expression to replace all Level 2 to "Level 2" with queries. The problem is that this regex catches "Level 2(without closing "). I want to catch Level 2 only if it has to quotes before AND after the words.



What is the best approach to do that?







javascript regex






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 17:48









FilipFilip

5512




5512













  • Can you add some sample text and actual vs expected output with your current regex?

    – Pushpesh Kumar Rajwanshi
    Nov 20 '18 at 17:51











  • Try (?<=")levelsd+(?=")

    – K.Dᴀᴠɪs
    Nov 20 '18 at 17:52











  • I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

    – Filip
    Nov 20 '18 at 17:52











  • Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

    – Wiktor Stribiżew
    Nov 20 '18 at 17:52











  • @WiktorStribiżew not working. The callback is not called. Is this in the ES5?

    – Filip
    Nov 20 '18 at 17:56



















  • Can you add some sample text and actual vs expected output with your current regex?

    – Pushpesh Kumar Rajwanshi
    Nov 20 '18 at 17:51











  • Try (?<=")levelsd+(?=")

    – K.Dᴀᴠɪs
    Nov 20 '18 at 17:52











  • I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

    – Filip
    Nov 20 '18 at 17:52











  • Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

    – Wiktor Stribiżew
    Nov 20 '18 at 17:52











  • @WiktorStribiżew not working. The callback is not called. Is this in the ES5?

    – Filip
    Nov 20 '18 at 17:56

















Can you add some sample text and actual vs expected output with your current regex?

– Pushpesh Kumar Rajwanshi
Nov 20 '18 at 17:51





Can you add some sample text and actual vs expected output with your current regex?

– Pushpesh Kumar Rajwanshi
Nov 20 '18 at 17:51













Try (?<=")levelsd+(?=")

– K.Dᴀᴠɪs
Nov 20 '18 at 17:52





Try (?<=")levelsd+(?=")

– K.Dᴀᴠɪs
Nov 20 '18 at 17:52













I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

– Filip
Nov 20 '18 at 17:52





I want to replace Excel Level 2 to Excel "Level 2" to refine some search results.

– Filip
Nov 20 '18 at 17:52













Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

– Wiktor Stribiżew
Nov 20 '18 at 17:52





Try .replace(/"[^"]*"|b(Levels+d+)/g, (x,y) => y ? `"${y}"` : x )

– Wiktor Stribiżew
Nov 20 '18 at 17:52













@WiktorStribiżew not working. The callback is not called. Is this in the ES5?

– Filip
Nov 20 '18 at 17:56





@WiktorStribiżew not working. The callback is not called. Is this in the ES5?

– Filip
Nov 20 '18 at 17:56












3 Answers
3






active

oldest

votes


















0














You may use






var s = '"Level 3 protected": Level 4 here and "another Level 5"';
s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
console.log(s);





Details





  • (^|[^"]) - Group 1 ($1): start of string or any char but a double quote


  • (Levels+d+) - Group 2 ($2): Level, 1+ whitespaces, 1+ digits


  • (?!["d]) - no digit or double quote to the left of the current location is allowed.


See the regex demo.






share|improve this answer































    0














    If you just want to capture every occurrence of Levels+d+ and replace it with "Levels+d+" provided it is not enclosed by doublequotes from both sides, you may use try using this regex,



    ([^"]|^)(Levels+d+)([^"]|$)


    and replace it with,



    1"2"3


    Check here for a demo



    This will not choose a text for replacement of type Label 2" or "Label 2 or "Label 2" and only replace when Label 2 when it is not surrounded by double quote from either side.






    share|improve this answer





















    • 1





      Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

      – Filip
      Nov 20 '18 at 17:57











    • @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

      – Pushpesh Kumar Rajwanshi
      Nov 20 '18 at 18:02











    • @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

      – Wiktor Stribiżew
      Nov 20 '18 at 18:04













    • oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

      – Pushpesh Kumar Rajwanshi
      Nov 20 '18 at 18:05











    • Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

      – Filip
      Nov 20 '18 at 18:08



















    0














    Not sure if you want to replace "Level 2 and Level 2" or not, so I offer solutions for both scenarios:



    1) If you want to replace only those with not even a single ":



    (?<!")(Levelsd+)(?!")



    see https://regex101.com/r/Nc7b5h/1



    This uses a negative look-behind and a negative look-ahead






    2) However, if you also want to replace those with only one ", try this:



    (?!"Levelsd+")(?<!")"?Levelsd+"?



    https://regex101.com/r/qL5Li5/1/



    Set your match group based on whether you want to replace the single " or not:



    var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

    s.replace(/(?!"Levelsd+")(?<!")"?(Levelsd+)"?/g, '"$1"');

    //> 'This "Level 2" is "Level 2" a "Level 2" test "Level 2" :)'


    or



    var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

    s.replace(/(?!"Levelsd+")(?<!")("?Levelsd+"?)/g, '"$1"');

    //> 'This "Level 2" is ""Level 2" a "Level 2"" test "Level 2" :)'


    The trick here was to first perform a negative look-ahead for the forbidden case of a match with two ", before doing anything else.



    General Notes



    If you don't want to use a look-behind expression ((?<!")) as older browsers (pre-ES2018) won't support that, just use (^|[^"]) instead, as other suggested. Just don't forget to restore its contents in the replacement :)



    e.g. s.replace(/(?!"Levelsd+")(^|[^"])"?(Levelsd+)"?/g, '$1"$2"');






    share|improve this answer





















    • 1





      Javascript does not support look behind.

      – Rahul
      Nov 20 '18 at 19:12













    • @Rahul Actually they are supported since ES 2018 :D

      – Jay
      Nov 20 '18 at 19:18











    • Is there an official release ?

      – Rahul
      Nov 20 '18 at 20:00











    • @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

      – Jay
      Nov 20 '18 at 20:06











    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%2f53398711%2fjavascript-regex-negative-lookahead-match%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You may use






    var s = '"Level 3 protected": Level 4 here and "another Level 5"';
    s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
    console.log(s);





    Details





    • (^|[^"]) - Group 1 ($1): start of string or any char but a double quote


    • (Levels+d+) - Group 2 ($2): Level, 1+ whitespaces, 1+ digits


    • (?!["d]) - no digit or double quote to the left of the current location is allowed.


    See the regex demo.






    share|improve this answer




























      0














      You may use






      var s = '"Level 3 protected": Level 4 here and "another Level 5"';
      s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
      console.log(s);





      Details





      • (^|[^"]) - Group 1 ($1): start of string or any char but a double quote


      • (Levels+d+) - Group 2 ($2): Level, 1+ whitespaces, 1+ digits


      • (?!["d]) - no digit or double quote to the left of the current location is allowed.


      See the regex demo.






      share|improve this answer


























        0












        0








        0







        You may use






        var s = '"Level 3 protected": Level 4 here and "another Level 5"';
        s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
        console.log(s);





        Details





        • (^|[^"]) - Group 1 ($1): start of string or any char but a double quote


        • (Levels+d+) - Group 2 ($2): Level, 1+ whitespaces, 1+ digits


        • (?!["d]) - no digit or double quote to the left of the current location is allowed.


        See the regex demo.






        share|improve this answer













        You may use






        var s = '"Level 3 protected": Level 4 here and "another Level 5"';
        s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
        console.log(s);





        Details





        • (^|[^"]) - Group 1 ($1): start of string or any char but a double quote


        • (Levels+d+) - Group 2 ($2): Level, 1+ whitespaces, 1+ digits


        • (?!["d]) - no digit or double quote to the left of the current location is allowed.


        See the regex demo.






        var s = '"Level 3 protected": Level 4 here and "another Level 5"';
        s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
        console.log(s);





        var s = '"Level 3 protected": Level 4 here and "another Level 5"';
        s = s.replace(/(^|[^"])(Levels+d+)(?!["d])/g, '$1"$2"');
        console.log(s);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 18:13









        Wiktor StribiżewWiktor Stribiżew

        319k16139221




        319k16139221

























            0














            If you just want to capture every occurrence of Levels+d+ and replace it with "Levels+d+" provided it is not enclosed by doublequotes from both sides, you may use try using this regex,



            ([^"]|^)(Levels+d+)([^"]|$)


            and replace it with,



            1"2"3


            Check here for a demo



            This will not choose a text for replacement of type Label 2" or "Label 2 or "Label 2" and only replace when Label 2 when it is not surrounded by double quote from either side.






            share|improve this answer





















            • 1





              Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

              – Filip
              Nov 20 '18 at 17:57











            • @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:02











            • @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

              – Wiktor Stribiżew
              Nov 20 '18 at 18:04













            • oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:05











            • Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

              – Filip
              Nov 20 '18 at 18:08
















            0














            If you just want to capture every occurrence of Levels+d+ and replace it with "Levels+d+" provided it is not enclosed by doublequotes from both sides, you may use try using this regex,



            ([^"]|^)(Levels+d+)([^"]|$)


            and replace it with,



            1"2"3


            Check here for a demo



            This will not choose a text for replacement of type Label 2" or "Label 2 or "Label 2" and only replace when Label 2 when it is not surrounded by double quote from either side.






            share|improve this answer





















            • 1





              Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

              – Filip
              Nov 20 '18 at 17:57











            • @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:02











            • @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

              – Wiktor Stribiżew
              Nov 20 '18 at 18:04













            • oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:05











            • Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

              – Filip
              Nov 20 '18 at 18:08














            0












            0








            0







            If you just want to capture every occurrence of Levels+d+ and replace it with "Levels+d+" provided it is not enclosed by doublequotes from both sides, you may use try using this regex,



            ([^"]|^)(Levels+d+)([^"]|$)


            and replace it with,



            1"2"3


            Check here for a demo



            This will not choose a text for replacement of type Label 2" or "Label 2 or "Label 2" and only replace when Label 2 when it is not surrounded by double quote from either side.






            share|improve this answer















            If you just want to capture every occurrence of Levels+d+ and replace it with "Levels+d+" provided it is not enclosed by doublequotes from both sides, you may use try using this regex,



            ([^"]|^)(Levels+d+)([^"]|$)


            and replace it with,



            1"2"3


            Check here for a demo



            This will not choose a text for replacement of type Label 2" or "Label 2 or "Label 2" and only replace when Label 2 when it is not surrounded by double quote from either side.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 '18 at 19:23

























            answered Nov 20 '18 at 17:56









            Pushpesh Kumar RajwanshiPushpesh Kumar Rajwanshi

            8,49021027




            8,49021027








            • 1





              Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

              – Filip
              Nov 20 '18 at 17:57











            • @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:02











            • @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

              – Wiktor Stribiżew
              Nov 20 '18 at 18:04













            • oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:05











            • Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

              – Filip
              Nov 20 '18 at 18:08














            • 1





              Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

              – Filip
              Nov 20 '18 at 17:57











            • @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:02











            • @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

              – Wiktor Stribiżew
              Nov 20 '18 at 18:04













            • oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

              – Pushpesh Kumar Rajwanshi
              Nov 20 '18 at 18:05











            • Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

              – Filip
              Nov 20 '18 at 18:08








            1




            1





            Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

            – Filip
            Nov 20 '18 at 17:57





            Not working ok, because it also replaces "Level 2" with ""Level 2"" regex101.com/r/kuTf1k/1

            – Filip
            Nov 20 '18 at 17:57













            @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

            – Pushpesh Kumar Rajwanshi
            Nov 20 '18 at 18:02





            @Filip: Ok I've updated the answer to ensure it is not already surrounded by double quotes. Can you check now?

            – Pushpesh Kumar Rajwanshi
            Nov 20 '18 at 18:02













            @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

            – Wiktor Stribiżew
            Nov 20 '18 at 18:04







            @PushpeshKumarRajwanshi You suggest something that only works with ECMAScript 2018 but even ES6 syntax does not work for OP.

            – Wiktor Stribiżew
            Nov 20 '18 at 18:04















            oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

            – Pushpesh Kumar Rajwanshi
            Nov 20 '18 at 18:05





            oh ok Wiktor, sorry I forgot it was javascript where look behind doesn't work :( Let me figure out something else.

            – Pushpesh Kumar Rajwanshi
            Nov 20 '18 at 18:05













            Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

            – Filip
            Nov 20 '18 at 18:08





            Yeah, I need something that works natively in browser as this is in a simple file not transpilled by babel.

            – Filip
            Nov 20 '18 at 18:08











            0














            Not sure if you want to replace "Level 2 and Level 2" or not, so I offer solutions for both scenarios:



            1) If you want to replace only those with not even a single ":



            (?<!")(Levelsd+)(?!")



            see https://regex101.com/r/Nc7b5h/1



            This uses a negative look-behind and a negative look-ahead






            2) However, if you also want to replace those with only one ", try this:



            (?!"Levelsd+")(?<!")"?Levelsd+"?



            https://regex101.com/r/qL5Li5/1/



            Set your match group based on whether you want to replace the single " or not:



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")"?(Levelsd+)"?/g, '"$1"');

            //> 'This "Level 2" is "Level 2" a "Level 2" test "Level 2" :)'


            or



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")("?Levelsd+"?)/g, '"$1"');

            //> 'This "Level 2" is ""Level 2" a "Level 2"" test "Level 2" :)'


            The trick here was to first perform a negative look-ahead for the forbidden case of a match with two ", before doing anything else.



            General Notes



            If you don't want to use a look-behind expression ((?<!")) as older browsers (pre-ES2018) won't support that, just use (^|[^"]) instead, as other suggested. Just don't forget to restore its contents in the replacement :)



            e.g. s.replace(/(?!"Levelsd+")(^|[^"])"?(Levelsd+)"?/g, '$1"$2"');






            share|improve this answer





















            • 1





              Javascript does not support look behind.

              – Rahul
              Nov 20 '18 at 19:12













            • @Rahul Actually they are supported since ES 2018 :D

              – Jay
              Nov 20 '18 at 19:18











            • Is there an official release ?

              – Rahul
              Nov 20 '18 at 20:00











            • @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

              – Jay
              Nov 20 '18 at 20:06
















            0














            Not sure if you want to replace "Level 2 and Level 2" or not, so I offer solutions for both scenarios:



            1) If you want to replace only those with not even a single ":



            (?<!")(Levelsd+)(?!")



            see https://regex101.com/r/Nc7b5h/1



            This uses a negative look-behind and a negative look-ahead






            2) However, if you also want to replace those with only one ", try this:



            (?!"Levelsd+")(?<!")"?Levelsd+"?



            https://regex101.com/r/qL5Li5/1/



            Set your match group based on whether you want to replace the single " or not:



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")"?(Levelsd+)"?/g, '"$1"');

            //> 'This "Level 2" is "Level 2" a "Level 2" test "Level 2" :)'


            or



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")("?Levelsd+"?)/g, '"$1"');

            //> 'This "Level 2" is ""Level 2" a "Level 2"" test "Level 2" :)'


            The trick here was to first perform a negative look-ahead for the forbidden case of a match with two ", before doing anything else.



            General Notes



            If you don't want to use a look-behind expression ((?<!")) as older browsers (pre-ES2018) won't support that, just use (^|[^"]) instead, as other suggested. Just don't forget to restore its contents in the replacement :)



            e.g. s.replace(/(?!"Levelsd+")(^|[^"])"?(Levelsd+)"?/g, '$1"$2"');






            share|improve this answer





















            • 1





              Javascript does not support look behind.

              – Rahul
              Nov 20 '18 at 19:12













            • @Rahul Actually they are supported since ES 2018 :D

              – Jay
              Nov 20 '18 at 19:18











            • Is there an official release ?

              – Rahul
              Nov 20 '18 at 20:00











            • @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

              – Jay
              Nov 20 '18 at 20:06














            0












            0








            0







            Not sure if you want to replace "Level 2 and Level 2" or not, so I offer solutions for both scenarios:



            1) If you want to replace only those with not even a single ":



            (?<!")(Levelsd+)(?!")



            see https://regex101.com/r/Nc7b5h/1



            This uses a negative look-behind and a negative look-ahead






            2) However, if you also want to replace those with only one ", try this:



            (?!"Levelsd+")(?<!")"?Levelsd+"?



            https://regex101.com/r/qL5Li5/1/



            Set your match group based on whether you want to replace the single " or not:



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")"?(Levelsd+)"?/g, '"$1"');

            //> 'This "Level 2" is "Level 2" a "Level 2" test "Level 2" :)'


            or



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")("?Levelsd+"?)/g, '"$1"');

            //> 'This "Level 2" is ""Level 2" a "Level 2"" test "Level 2" :)'


            The trick here was to first perform a negative look-ahead for the forbidden case of a match with two ", before doing anything else.



            General Notes



            If you don't want to use a look-behind expression ((?<!")) as older browsers (pre-ES2018) won't support that, just use (^|[^"]) instead, as other suggested. Just don't forget to restore its contents in the replacement :)



            e.g. s.replace(/(?!"Levelsd+")(^|[^"])"?(Levelsd+)"?/g, '$1"$2"');






            share|improve this answer















            Not sure if you want to replace "Level 2 and Level 2" or not, so I offer solutions for both scenarios:



            1) If you want to replace only those with not even a single ":



            (?<!")(Levelsd+)(?!")



            see https://regex101.com/r/Nc7b5h/1



            This uses a negative look-behind and a negative look-ahead






            2) However, if you also want to replace those with only one ", try this:



            (?!"Levelsd+")(?<!")"?Levelsd+"?



            https://regex101.com/r/qL5Li5/1/



            Set your match group based on whether you want to replace the single " or not:



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")"?(Levelsd+)"?/g, '"$1"');

            //> 'This "Level 2" is "Level 2" a "Level 2" test "Level 2" :)'


            or



            var s='This "Level 2" is "Level 2 a Level 2" test Level 2 :)'

            s.replace(/(?!"Levelsd+")(?<!")("?Levelsd+"?)/g, '"$1"');

            //> 'This "Level 2" is ""Level 2" a "Level 2"" test "Level 2" :)'


            The trick here was to first perform a negative look-ahead for the forbidden case of a match with two ", before doing anything else.



            General Notes



            If you don't want to use a look-behind expression ((?<!")) as older browsers (pre-ES2018) won't support that, just use (^|[^"]) instead, as other suggested. Just don't forget to restore its contents in the replacement :)



            e.g. s.replace(/(?!"Levelsd+")(^|[^"])"?(Levelsd+)"?/g, '$1"$2"');







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 21 '18 at 8:32

























            answered Nov 20 '18 at 19:05









            JayJay

            1,306511




            1,306511








            • 1





              Javascript does not support look behind.

              – Rahul
              Nov 20 '18 at 19:12













            • @Rahul Actually they are supported since ES 2018 :D

              – Jay
              Nov 20 '18 at 19:18











            • Is there an official release ?

              – Rahul
              Nov 20 '18 at 20:00











            • @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

              – Jay
              Nov 20 '18 at 20:06














            • 1





              Javascript does not support look behind.

              – Rahul
              Nov 20 '18 at 19:12













            • @Rahul Actually they are supported since ES 2018 :D

              – Jay
              Nov 20 '18 at 19:18











            • Is there an official release ?

              – Rahul
              Nov 20 '18 at 20:00











            • @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

              – Jay
              Nov 20 '18 at 20:06








            1




            1





            Javascript does not support look behind.

            – Rahul
            Nov 20 '18 at 19:12







            Javascript does not support look behind.

            – Rahul
            Nov 20 '18 at 19:12















            @Rahul Actually they are supported since ES 2018 :D

            – Jay
            Nov 20 '18 at 19:18





            @Rahul Actually they are supported since ES 2018 :D

            – Jay
            Nov 20 '18 at 19:18













            Is there an official release ?

            – Rahul
            Nov 20 '18 at 20:00





            Is there an official release ?

            – Rahul
            Nov 20 '18 at 20:00













            @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

            – Jay
            Nov 20 '18 at 20:06





            @Rahul ecma-international.org/ecma-262/9.0/#prod-Assertion

            – Jay
            Nov 20 '18 at 20:06


















            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%2f53398711%2fjavascript-regex-negative-lookahead-match%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

            How to send String Array data to Server using php in android

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

            Is anime1.com a legal site for watching anime?