Инвертировать группы захвата в регулярном выражении - PullRequest
0 голосов
/ 06 февраля 2019

Учитывая это (обратите внимание на группы захвата):

/^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/

Я хочу это (обратите внимание, что группы захвата были инвертированы):

/^(\w+\[\w+\]\[\w+\]\[)\d+(\]\[\w+\]\[)\d+(\]\[\w+\])$/

Что я пытался:

str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString()
noncaptured = [];
captured = [];
insideCapture = false;
for (var i = 0, position = 1; i < str.length; i++) {
   if( str.charAt(i) != '(' && insideCapture == false ){
     noncaptured.push([position, str.charAt(i) ] );
   } else {
     if( str.charAt(i) != '(' ){
        position += 1;
     }

     captured.push([position, str.charAt(i) ]);
     insideCapture = true;

     if( str.charAt(i) == ')' ){
       captured.push([position, str.charAt(i)]);
       insideCapture = false;
       position += 1;
     }
   }
}

var arr = captured.concat(insideCapture);
arr.sort(function(){
  if (a[0] === b[0]) {
        return 0;
    }
    else {
        return (a[0] < b[0]) ? -1 : 1;
    }   
})

Я ищу чистый алгоритм.Решение ES6 приветствуется.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Даже если я не 100% уверен, что следующий будет работать во всех случаях, которые могут вам понадобиться, это может быть альтернативный подход: Отменить все скобки и добавить скобки после ^ и до $

const str1 = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str2 = /^\w+(\[\w+\])\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const str3 = /^(\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\])$/.toString();
const str4 = /^\w+\[\w+\]\[\w+\]\[\d+\]\[\w+\]\[\d+\]\[\w+\]$/.toString();

const replaceMap = {"(": ")", ")": "(", "^": "^(", "$": ")$"};

const reverse = (str) =>
{
    return str.replace(/[(,),^, $]/g, function(match)
    {
        return replaceMap[match];
    });
}

console.log(reverse(str1));
console.log(reverse(str2));
console.log(reverse(str3));
console.log(reverse(str4));
0 голосов
/ 06 февраля 2019

Предполагая, что не будет вложенных скобок, как в примере, я бы выделил части строки между начальным /^ и завершающим $/, а затем использовал бы регулярное выражение для захвата несимволы в скобках и замените их на группу, заключенную в скобки.Кроме того, после символов, не являющихся скобками, необязательно совпадают ( s, за которыми следуют символы без скобок, затем ), и, если эта группа соответствует, замените только на эту группу (без скобок):

([^(]+)(?:\(([^)]+)\))?

Заменить на

($1)$2

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

const str = /^\w+\[\w+\]\[\w+\]\[(\d+)\]\[\w+\]\[(\d+)\]\[\w+\]$/.toString();
const sliced = str.slice(2, str.length - 2);
const output = '/^' + sliced.replace(/([^(]+)(?:\(([^)]+)\))?/g, '($1)$2') + '$/';
console.log(output);
([^(]+)(?:\(([^)]+)\))?

означает:

  • ([^(]+) - Non- ( символов
  • (?:\(([^)]+)\))? Не обязательно- группа захвата, содержащая:
    • \( - ведущий (
    • ([^)]+) - не- ) символы, захваченные в группе
    • \) -Трейлинг )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...