Регулярное выражение: заменить перед словом

#javascript #regex

#javascript #регулярное выражение

Вопрос:

У меня есть эта строка:

 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]);
* });
`;
  

и я хотел бы внести в него некоторые изменения, например добавить перед каждым pm.expect an nt и перед каждым pm.test an n

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

Я хочу, чтобы в итоге получилось что-то вроде этого :

 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]);
});
  

Комментарии:

1. Что-то вроде replace(/^*/gm, '') ?

Ответ №1:

Вы можете использовать replace и его обратный вызов с захватом групп.

 ^(*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   'nt'   g2
  } else {
    return g1   'n'   g3
  }
})

console.log(op)  

Ответ №2:

TL; DR;

Вы можете использовать предварительные просмотры для обработки «вставки» текста перед совпадением, и вы не учли пробелы.

 function clean() {
  
  const string = document.getElementById("input").value;
  const cleaned = string
      .replace(/n/g, "")
      .replace(/s */g, ' ')
      .replace(/*/g, "")               
      .replace(/@[a-z] /g, "")        
      .replace(/({)s*(?=pm.expect)/g,'$1nt')
      .replace(/s*(?=pm.test)/g,'n')
      .replace(/(;)s*(?=});)/g, '$1n');
  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>  

Объяснение

Звучит так, как будто вы хотели бы сопоставить позицию, а не фактический текст. Как в

Я хочу сопоставить позицию между фигурной скобкой у символов pm.expect .

Многие библиотеки регулярных выражений поддерживают поисковые выражения именно для этого сценария. К счастью, Javascript поддерживает предварительные просмотры. К сожалению, только Chrome поддерживает поисковые системы, но это помогает нам на полпути, а остальное может быть достигнуто с помощью захваченных групп.

Сначала мы сопоставляем фигурные скобки в группе, чтобы мы могли использовать обратную ссылку в строке замены:

 ({)
  

Далее мы используем предварительный просмотр. Это выражение будет оценивать символы, которые следуют за ними, но оно не будет захватывать их и не будет перемещать указатель вперед. Это выражение будет соответствовать только фигурной скобке, но оно будет соответствовать только фигурным скобкам, за которыми следует желаемое выражение:

 (?=pm.expect)
  

Соединяя это вместе, мы получаем:

 ({)(?=pm.expect)
  

При замене вы можете либо использовать {nt , либо, если хотите пофантазировать, вы можете использовать обратную ссылку на захваченную группу, $1nt .

Вы также можете использовать предварительный просмотр для pm.test :

 (?=pm.test)
  

Это выражение будет соответствовать строке нулевой длины, то есть в основном позиции перед pm.test . Если вы сделаете замену, вы, по сути, будете вставлять текст, а не заменять его.

Наконец, вы не учли пробелы. Между { и pm.expect есть пробел, который мешал вашим регулярным выражениям соответствовать чему-либо.

Ответ №3:

Сделать:

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

и вы получите:

 "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]); });"
  

Ответ №4:

 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, 'rn$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>