简体   繁体   中英

Regex: replace in front of word

I have this string:

const string = `
* @test
* pm.test("Response time is less than 200ms", function() {
*   pm.expect(pm.response.responseTime).to.be.below(500);
* });
* pm.test("Successful POST request", function() {
*   pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);
* });
`;

and i would like to do some changes on it like add in front of every pm.expect an \\n\\t and in front of every pm.test an \\n

const cleaned = string
    .replace(/\n/g, "")
    .replace(/\s */g, ' ')
    .replace(/\*/g, "")               
    .replace(/@[a-z]+/g, "")        
    .replace(/{(pm.expect)/g,'\n\t') // the problem is here
    .replace(/(pm.test)/g,'\n') // the problem is here

I want to have in the end something like this :

pm.test("Response time is less than 200ms", function() {
  pm.expect(pm.response.responseTime).to.be.below(500);
});

pm.test("Successful POST request", function() {
  pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);
});

You can use replace and it's callback with capturing groups.

^(\*\s*)(?:(pm.test)|(pm.expect)
   |          |           |__________   (Group 3, g3)       
   |          |______________________   (Group 2, g3)
   |_________________________________   (Group 1, g1)

 const string = ` * @test * pm.test("Response time is less than 200ms", function() { * pm.expect(pm.response.responseTime).to.be.below(500); * }); * pm.test("Successful POST request", function() { * pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]); * }); `; let op = string.replace(/^(\\*\\s*)(?:(pm.test)|(pm.expect))/gm,(match,g1,g2,g3)=>{ if(g2){ return g1 + '\\n\\t' + g2 } else { return g1 + '\\n' + g3 } }) console.log(op) 

TL;DR;

You can use lookaheads to handle "inserting" text in front of a match, and you didn't take spaces into account.

 function clean() { const string = document.getElementById("input").value; const cleaned = string .replace(/\\n/g, "") .replace(/\\s */g, ' ') .replace(/\\*/g, "") .replace(/@[az]+/g, "") .replace(/({)\\s*(?=pm.expect)/g,'$1\\n\\t') .replace(/\\s*(?=pm.test)/g,'\\n') .replace(/(;)\\s*(?=}\\);)/g, '$1\\n'); document.getElementById("result").textContent = cleaned; } 
 <textarea id="input" style="width:100%; height: 10em;"> * @test * pm.test("Response time is less than 200ms", function() { * pm.expect(pm.response.responseTime).to.be.below(500); * }); * pm.test("Successful POST request", function() { * pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]); * }); </textarea> <button onclick="clean()">Clean</button> <pre id="result"></pre> 

Explantaion

It sounds like you'd like to match a position rather than actual text. As in

I want to match the position between a curly brace at the characters pm.expect .

Many regex libraries support lookaround expressions for exactly this scenario. Fortunately Javascript supports lookaheads. Unfortunately only Chrome supports lookbehinds, but it gets us halfway there and the rest can be accomplished with captured groups.

First, we match the curly brace in a group so that we can use a back reference in the replace string:

({)

Next we use a lookahead. This expression will evaluate the characters which follow, but it will not capture them nor will it move the pointer forward. This expression will match only the curly brace, but it will only match curly braces which are followed by the desired expression:

(?=pm.expect)

Putting this together, we get:

({)(?=pm.expect)

In your replace, you can either use {\\n\\t or, if you want to get fancy, you can use a back reference to the captured group, $1\\n\\t .

You can also use a lookahead for pm.test :

(?=pm.test)

This expression will match a zero-length string , so basically the position before pm.test . If you do a replace, you'll essentially be inserting text rather than replacing it.

Finally, you didn't take spaces into account. There's a space in between { and pm.expect which was preventing your regexes from matching anything.

Do:

const cleaned = string
    .replace(/\n/g, "")
    .replace(/\s */g, ' ')
    .replace(/\*/g, "")               
    .replace(/@[a-z]+/g, "")
    .replace(/pm.expect/gi,"\n\tpm.expect")
    .replace(/pm.test/gi,"\npm.test")
    .trim()

and you'll get:

"pm.test(\"Response time is less than 200ms\", function() { 
    pm.expect(pm.response.responseTime).to.be.below(500); }); 
pm.test(\"Successful POST request\", function() { 
    pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]); });"

 const string = ` * @test * pm.test("Response time is less than 200ms", function() { * pm.expect(pm.response.responseTime).to.be.below(500); * }); * pm.test("Successful POST request", function() { * pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]); * }); `; const cleaned = string .replace(/\\*\\s+/g, '') .replace(/@\\w+/g, '') .replace(/(pm\\.test)/g, '\\r\\n$1') .replace(/(pm\\.expect)/g, '\\t$1') .trim(); // To show the result. document.getElementsByTagName('textarea')[0].value = cleaned; 
 <textarea disabled style="width:100%; height:400px;"></textarea> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM