Что такое поддержка просмотра назад в JS? Как его заменить?

У меня есть строка, и я хочу заменить каждую букву «i», которая НЕ следует за какой-либо другой буквой i, и заменить ее на «z». Я знаю, что существует отрицательный взгляд вперед и взгляд назад.

Результаты должны быть:

i => z
iki => zkz
iiki => iikz
ii => ii
iii => iii

Я пытался использовать это:

/(?<!i)i(?!i)/gi

и это не удалось и выдало ошибку: Invalid regex group.

Пока что

/i(?!i)/gi

работает нормально, но соответствует второму «i» в этом: «ii».

Есть ли другой способ?

Что такое поддержка lookbehind в JS, если она есть?


person SkillGG    schedule 10.02.2019    source источник


Ответы (3)


В вашем случае вам действительно не нужно смотреть назад:

'iiki'.replace(/i+/g, (m0) => m0.length > 1 ? m0 : 'z')

Вы можете просто использовать функцию в качестве замены и проверить длину совпадающей строки.

Вот все ваши тестовые случаи:

function test(input, expect) {
  const result = input.replace(/i+/g, (m0) => m0.length > 1 ? m0 : 'z');
  console.log(input + " => " + result + " // " + (result === expect ? "Good" : "ERROR"));
}

test('i', 'z');
test('iki', 'zkz');
test('iiki', 'iikz');
test('ii', 'ii');
test('iii', 'iii');

person melpomene    schedule 10.02.2019

Lookbehind в регулярных выражениях JavaScript — это совершенно новое явление. На момент написания этой статьи он поддерживается только в V8 (в Chrome , Chromium, Brave...), а не другими движками.

Здесь есть много вопросов с ответами о том, как обойти отсутствие просмотра назад, например как этот.

В этой статье Стивена Левитана также показаны способы обхода отсутствия этой функции. .

Я хочу заменить каждое «i», за которым НЕ следует/за которым НЕ следует какой-либо другой i, и заменить его на «z»

Это довольно легко сделать без просмотра вперед или назад, используя заполнители и группу захвата. Вы можете зафиксировать то, что следует за i:

const rex = /i(i+|.|$)/g;

... и затем условно заменить его, если то, что было захвачено, не является i или серией i:

const result = input.replace(rex, (m, c) => {
    return c[0] === "i" ? m : "z" + c;
});

Живой пример:

const rex = /i(i+|.|$)/g;
function test(input, expect) {
    const result = input.replace(rex, (m, c) => {
        return c[0] === "i" ? m : "z" + c;
    });
    console.log(input, result, result === expect ? "Good" : "ERROR");
}

test("i", "z");
test("iki", "zkz");
test("iiki", "iikz");
test("ii", "ii");
test("iii", "iii");

person T.J. Crowder    schedule 10.02.2019

Один хак, который вы можете использовать в этом случае. изменяет значение смещения на основе совпадения.

let arr = ['i','iki','iiki','ii','iii', 'ki']

arr.forEach(e=>{
  let value = e.replace(/i(?!i)/g, function(match,offset,string){
    return offset > 0 && string[offset-1] === 'i' ? 'i' : 'z'
  })
  console.log(value)
})

person Code Maniac    schedule 10.02.2019