вид сзади через реверс подход кажется самым легким здесь. Этот подход лучше всего подходит для коротких числовых шаблонов, подобных этому.
function revStr(str) {
return str.split('').reverse().join('');
}
var s = "--1--01001--1087---";
var rxp = /\d(?=[01])/g;
var result = revStr(revStr(s).replace(rxp, "#"));
document.write(result);
Логика:
\d(?=[01])
является обратным регулярным выражением для (?<=[01])\d
- Мы реверс строки ввода с
revStr(s)
функцией
- Мы обратный результатом замены снова, чтобы получить конечный результат.
ПРИМЕЧАНИЕ:
В случае, если вам нужен как переменная ширина взгляд-за и упреждающими в JavaScript, я могу рекомендовать чтение JavaScript Regex Lookbehind Redux статьи Стивена Levithan, где вы можете найти образец функция, показывающая, как реализовать это поведение, используя XRegExp. Вот функции:
// Simulating infinite-length leading lookbehind in JavaScript. Uses XRegExp.
// Captures within lookbehind are not included in match results. Lazy
// repetition in lookbehind may lead to unexpected results.
(function (XRegExp) {
function prepareLb(lb) {
// Allow mode modifier before lookbehind
var parts = /^((?:\(\?[\w$]+\))?)\(\?<([=!])([\s\S]*)\)$/.exec(lb);
return {
// $(?!\s) allows use of (?m) in lookbehind
lb: XRegExp(parts ? parts[1] + "(?:" + parts[3] + ")$(?!\\s)" : lb),
// Positive or negative lookbehind. Use positive if no lookbehind group
type: parts ? parts[2] === "=" : !parts
};
}
XRegExp.execLb = function (str, lb, regex) {
var pos = 0, match, leftContext;
lb = prepareLb(lb);
while (match = XRegExp.exec(str, regex, pos)) {
leftContext = str.slice(0, match.index);
if (lb.type === lb.lb.test(leftContext)) {
return match;
}
pos = match.index + 1;
}
return null;
};
XRegExp.testLb = function (str, lb, regex) {
return !!XRegExp.execLb(str, lb, regex);
};
XRegExp.searchLb = function (str, lb, regex) {
var match = XRegExp.execLb(str, lb, regex);
return match ? match.index : -1;
};
XRegExp.matchAllLb = function (str, lb, regex) {
var matches = [], pos = 0, match, leftContext;
lb = prepareLb(lb);
while (match = XRegExp.exec(str, regex, pos)) {
leftContext = str.slice(0, match.index);
if (lb.type === lb.lb.test(leftContext)) {
matches.push(match[0]);
pos = match.index + (match[0].length || 1);
} else {
pos = match.index + 1;
}
}
return matches;
};
XRegExp.replaceLb = function (str, lb, regex, replacement) {
var output = "", pos = 0, lastEnd = 0, match, leftContext;
lb = prepareLb(lb);
while (match = XRegExp.exec(str, regex, pos)) {
leftContext = str.slice(0, match.index);
if (lb.type === lb.lb.test(leftContext)) {
// Doesn't work correctly if lookahead in regex looks outside of the match
output += str.slice(lastEnd, match.index) + XRegExp.replace(match[0], regex, replacement);
lastEnd = match.index + match[0].length;
if (!regex.global) {
break;
}
pos = match.index + (match[0].length || 1);
} else {
pos = match.index + 1;
}
}
return output + str.slice(lastEnd);
};
}(XRegExp));
Каждая из этих функций принимает три аргумента: строка для поиска, шаблон просмотра назад в виде строки (можно использовать XRegExp расширения синтаксиса), а главное регулярное выражение. XRegExp.replaceLb
принимает четвертый аргумент для значения замены, которое может быть строкой или функцией.
Примеры использования следуют:
XRegExp.execLb("Fluffy cat", "(?i)(?<=fluffy\\W+)", XRegExp("(?i)(?<first>c)at"));
// -> ["cat", "c"]
// Result has named backref: result.first -> "c"
XRegExp.execLb("Fluffy cat", "(?i)(?<!fluffy\\W+)", /cat/i);
// -> null
XRegExp.testLb("Fluffy cat", "(?i)(?<=fluffy\\W+)", /cat/i);
// -> true
XRegExp.testLb("Fluffy cat", "(?i)(?<!fluffy\\W+)", /cat/i);
// -> false
XRegExp.searchLb("Catwoman's fluffy cat", "(?i)(?<=fluffy\\W+)", /cat/i);
// -> 18
XRegExp.searchLb("Catwoman's fluffy cat", "(?i)(?<!fluffy\\W+)", /cat/i);
// -> 0
XRegExp.matchAllLb("Catwoman's cats are fluffy cats", "(?i)(?<=fluffy\\W+)", /cat\w*/i);
// -> ["cats"]
XRegExp.matchAllLb("Catwoman's cats are fluffy cats", "(?i)(?<!fluffy\\W+)", /cat\w*/i);
// -> ["Catwoman", "cats"]
XRegExp.replaceLb("Catwoman's fluffy cat is a cat", "(?i)(?<=fluffy\\W+)", /cat/ig, "dog");
// -> "Catwoman's fluffy dog is a cat"
XRegExp.replaceLb("Catwoman's fluffy cat is a cat", "(?i)(?<!fluffy\\W+)", /cat/ig, "dog");
// -> "dogwoman's fluffy cat is a dog"
XRegExp.replaceLb("Catwoman's fluffy cat is a cat", "(?i)(?<!fluffy\\W+)", /cat/ig, function ($0) {
var first = $0.charAt(0);
return first === first.toUpperCase() ? "Dog" : "dog";
});
// -> "Dogwoman's fluffy cat is a dog"
Если вы не нуждаетесь в переменной ширины Двойник позади с переменной шириной, заглядывая вперёд, этот поворот подход, кажется, работает лучше всего для перекрытия матчей. И количество кода не так уж и велико. Кроме того, шаблоны регулярных выражений не так трудно отменить. –
Я нахожу это сказанным, но, похоже, нет другого выбора. На самом деле, иногда нам также нужно как смотреть, так и смотреть вперед (не часто: я думаю, я использовал его примерно 5 раз в течение 16 лет Perl, но все же). – FERcsI
Если вам нужен как внешний вид с переменной шириной, так и внешний вид в JavaScript, я могу порекомендовать прочитать статью [JavaScript Regex Lookbehind Redux] (http://blog.stevenlevithan.com/archives/javascript-regex-lookbehind) Стивен Левитан, где вы можете найти примерную функцию, показывающую, как реализовать это поведение с помощью [XRegExp] (https://github.com/slevithan/xregexp). –