Как добавить круглые скобки вокруг каждого совпадения регулярных выражений в jQuery / Javascript?

#javascript #jquery #regex

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

Вопрос:

Мне нужно добавить круглые скобки или «<>» вокруг каждого совпадения в регулярном выражении, у меня уже готовы все предложения регулярных выражений. Например:

Ввод:

 int a = 0;
  

Вывод:

 <int><a><=><0>
  

Есть еще одна вещь, которую я делаю, это «переводчик», он должен считывать арифметическое число в C и генерировать поток токенов. Так, например, «=» будет <assign_op> и «;» будет <end_of_statement> .
Приведенное выше предложение будет записано как:
<int><a><assign_op><0>

Вот код, над которым я работал:

 function translate() {
var input = 'int a = 0;'  
    'nint b = 5;'  
    'nint a = b   5;'  
    'nint c = a1 / 1;'  
    'ndouble a = 1;'  
    'nfloat a = 0;'  
    'na = 0;'  
    'nfloat a = b   1;'  
    'na = (b - c) * 5;';


var regex3 = new RegExp(/(((int|long int|double|long double|float) s*([a-zA-Z_] d*)*|([a-zA-Z_] d*))s*=s*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d );)|(((int|long int|double|long double|float) s*([a-zA-Z_] d*)*|([a-zA-Z_] d*))s*=(s*(*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d ))*s*[ -/*%]s*(*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d ))*)*s*;)/g);

var text = input.match(regex3);
var varTypes = ['int', 'double', 'float', 'long int', 'long double'];
var output = '';

text.forEach(line => {
    varTypes.forEach(type => {
        if (line.match(type))
            line = line.replace(type, '<'   type   '>');

    });
    if (line.match(/=/g)) {
        line = line.replace(/=/g, '<assign_op>')
    }
    if (line.match(/;/g)) {
        line = line.replace(/;/g, '<end_of_statement>');
    }
    if (line.match(/(/g)) {
        line = line.replace(/(/g, '<open_parenthesis>')
    }
    if (line.match(/)/g)) {
        line = line.replace(/)/g, '<close_parenthesis>')
    }
    if (line.match(/[ -*/%]/g)) {
        line = line.replace(/[ -*/%]/g, '<operator>')
    }
    if (line.match(/ {2}/g)) {
        line = line.replace(/ {2}/g, '<operator>')
    }
    output  = line   'n';
});

console.log(output);
  

}

О, извините, если у меня было много ошибок в написании на английском, а не носитель английского языка 🙂

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

1. Мне нравится регулярное выражение, но когда оно становится слишком сложным и нечитаемым, возможно, пришло время попробовать другой подход. Поскольку каждый фрагмент во входной переменной структурирован более или менее одинаково, возможно, попробуйте использовать substring для разделения строк на левую и правую части. Все справа, кроме точки с запятой, можно заключить в фигурные скобки, а точку с запятой можно просто заменить. В левой части вы можете проверить, начинается ли оно с типа, и заменить этот бит. То, что остается в левой части, можно поместить в собственный набор фигурных скобок. Дайте мне знать, если вы не следите, и я опубликую пример.

Ответ №1:

Я довольно долго работал над вашей сложной проблемой манипулирования строками…

Я пришел с идеей «словаря», упрощающей управление заменами. И я использовал пробелы для выделения элементов string для переноса с < помощью and > .

Взгляните на комментарии в коде. CodePen

 var input = 
    'int a = 0;'  
    'nint b = 5;'  
    'nint a = b   5;'  
    'nint c = a1 / 1;'  
    'ndouble a = 1;'  
    'nfloat a = 0;'  
    'na = 0;'  
    'nfloat a = b   1;'  
    'na = (b - c) * 5;'  
    'nlong int = (w - x) * 7;'   // Added to test the two words types
    'nlong double = (x - w) * 7;';   // Added to test the two words types

var dictionary = [
  {
    target: "long int",
    replacement: "long|int" // | to ensure keeping that space, will be restored later
  },
  {
    target: "long double",
    replacement: "long|double" // | to ensure keeping that space, will be restored later
  },

  {
    target: /=/g,
    replacement: "assign_op"
  },
  {
    target: /;/g,
    replacement: "end_of_statement"
  },
  {
    target: /(/g,
    replacement: "open_parenthesis"
  },
  {
    target: /)/g,
    replacement: "close_parenthesis"
  },
  {
    target: /[ -*/%]/g,
    replacement: "operator"
  },
  {
    target: / {2}/g,
    replacement: "operator"
  }
];


function translate(input) {

  //console.log(input);

  // Your unchanged regex
  var regex3 = new RegExp(/(((int|long int|double|long double|float) s*([a-zA-Z_] d*)*|([a-zA-Z_] d*))s*=s*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d );)|(((int|long int|double|long double|float) s*([a-zA-Z_] d*)*|([a-zA-Z_] d*))s*=(s*(*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d ))*s*[ -/*%]s*(*(([a-zA-Z_]*|[a-zA-Z_] d*)*|d*|d .d ))*)*s*;)/g);

  // An array of lines created by the use of your regex
  var lines_array = input.match(regex3);
  //console.log(lines_array);

  // The result variable
  var output = '';

  // Process each lines
  lines_array.forEach(line => {

    // Use the dictionary to replace some special cases
    // It adds spaces around the replacements to ensure word separation
    dictionary.forEach(translation => {
      if (line.match(translation.target)) {
        line = line.replace(translation.target, " " translation.replacement " ");  // Notice the spaces
      }
    });

    // Remove double spaces
    line = line.trim().replace(/s /g," ");

    // Use the spaces to get a word array to add the angle brackets
    var words = line.split(" ");
    words.forEach(word => {
      output  = "<" word ">";
    });

    // Re-add the line return
    output  = 'n';
  });

  // Final fixes on the whole result string
  output = output
    .replace(/|/g, " ")  // Restore the space in the "two words types" ( was replaced by a | )
    .replace(/<</g, "<") // Remove duplicate angle brackets
    .replace(/>>/g, ">")

  console.log(output);
}

// Run the function
translate(input);