Написание регулярного выражения в JavaScript для соответствия синтаксису префикса $ variable (как в скриптах Bash) - PullRequest
3 голосов
/ 02 июля 2019

Я пытаюсь написать регулярное выражение в JavaScript для поиска многострочного скрипта bash и извлечения всех имен переменных. Я не могу ни сам разобраться, ни найти сценарий, который делает именно то, что мне нужно.

Я получил это далеко:

var re = /(?:^|\W)\$(\w+)(?!\w)/g;
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5";
var matches = [];
while (match = re.exec(s)) {
  matches.push(match[1]);
}

Это даст мне «test1», «test3» и «test4». Но я также хотел бы получить "test2" и "test5".

Было бы также неплохо, если бы я мог получить "\ $", чтобы он НЕ совпадал, если бы он появился в строке. Другими словами, есть ли способ избежать строки "$" в тексте, чтобы она игнорировалась моим регулярным выражением? Таким образом, если в тексте появилось «\ $ 1.00», то не будет соответствовать «1», как это делает приведенное выше регулярное выражение.

Заранее благодарен за любую помощь или за то, что указал мне правильное направление.

PS Это на самом деле для Action Script 3, но все, что работает в JavaScript до ES6, должно работать в AS 3.

PPS Конечная цель - заменить эти совпадения переменными из хеш-значения ключа.

Ответы [ 4 ]

3 голосов
/ 02 июля 2019

Попробуйте сопоставить (?:\\\$\w+)|\$(\w+).Поскольку первая группа начинает сопоставление раньше, она завершит сопоставление первой;однако, как блок без захвата, не будет возвращен.

var re = /(?:\\\$\w+)|\$(\w+)/g;
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5\\$1.00";
var matches = [];
while (match = re.exec(s)) {
  match[1] && matches.push(match[1]);
}
console.log(matches);
3 голосов
/ 02 июля 2019

Вы можете использовать это регулярное выражение

(?<!\\)\$([^\W$]+)
  • (?<!\\) - Отрицательный взгляд, чтобы избежать \$, чтобы соответствовать
  • \$ - Соответствует $
  • ([^\W$]+) - Совпадение с чем угодно, кроме слова, не состоящего из слов и символа $

Демо

3 голосов
/ 02 июля 2019

Вы можете многократно совпадать с \$ (в этом случае ничего не делать) или $\w+ (в этом случае это неэкранированный знак доллара, указывающий начало переменной, которую вы хотите сопоставить). Используйте функцию заменителя, чтобы решить, оставить ли совпадение в покое или заменить его любой другой строкой:

const replacements = {
  test1: 'testone',
  test2: 'testtwo',
  test3: 'testthree',
  test4: 'testfour',
  test5: 'testfive'
};
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5 \\$1.00";
const result = s.replace(
  /\\\$|\$(\w+)/g,
  (match, g1) => match === '\\$'
    ? match // replace with the matched string - in other words, leave it unchanged
    : replacements[g1]
);
console.log(result);

На более новых движках вместо обратной косой черты можно смотреть отрицательно, что значительно упрощает логику, но не хорошее кросс-браузерное решение, поскольку оно будет работать только в новых средах:

const replacements = {
  test1: 'testone',
  test2: 'testtwo',
  test3: 'testthree',
  test4: 'testfour',
  test5: 'testfive'
};
var s = "test $test1 testagain$test2 testyetagain $test3 $test4$test5 \\$1.00";
const result = s.replace(
  /(?<!\\)\$(\w+)/g,
  (_, g1) => replacements[g1]
);
console.log(result);
2 голосов
/ 02 июля 2019

Это выражение

(?:\\{2,}\$[0-9.]+)|\$([^$\s]+)

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

(?:\\{2,}\$[0-9.]+)

и возвращает нужные данные с использованием группы захвата

([^$\s]+)

Демо

const regex = /(?:\\{2,}\$[0-9.]+)|\$([^$\s]+)/g;
const str = `test \$test1 testagain\$test2 testyetagain \$test3 \$test4\$test5 \\\\\$1.00 \\\\\\\\\\\\\$1.00

`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Схема RegEx

jex.im визуализирует регулярные выражения:

enter image description here

...