阿里云主机折上折
  • 微信号
Current Site:Index > Regular expression lookbehind assertion

Regular expression lookbehind assertion

Author:Chuan Chen 阅读数:54810人阅读 分类: JavaScript

ECMAScript 8 Regular Expression Lookbehind Assertions

ECMAScript 8 (ES2017) introduced lookbehind assertions in regular expressions, including positive lookbehind and negative lookbehind assertions. These new features allow developers to more precisely match content before or after specific patterns in strings without including those patterns in the match results.

Positive Lookbehind Assertions

Positive lookbehind assertions use the (?<=...) syntax, indicating that a pattern must be matched before the desired content. This preceding pattern is not included in the match result.

const str = 'ECMAScript 8 was released in 2017';
const regex = /(?<=\bECMAScript\s)\d+/;
const match = str.match(regex);
console.log(match[0]); // Output: 8

In this example, the regular expression matches the digits \d+, but only if they are preceded by the word "ECMAScript ". The match result is "8", and "ECMAScript " is not included in the result.

Positive lookbehind assertions are particularly useful for handling scenarios like currencies or units:

const prices = 'Apple$5, Banana$3, Orange$2';
const regex = /(?<=\$)\d+/g;
const matches = prices.match(regex);
console.log(matches); // Output: ["5", "3", "2"]

Negative Lookbehind Assertions

Negative lookbehind assertions use the (?<!...) syntax, indicating that a pattern must not be present before the desired content.

const text = 'foo123 bar456 baz789';
const regex = /(?<!bar)\d{3}/g;
const matches = text.match(regex);
console.log(matches); // Output: ["123", "789"]

This example matches all three-digit numbers but excludes those preceded by "bar". Thus, "456" is not matched.

Negative lookbehind assertions are useful for excluding specific prefixes:

const data = 'active_user inactive_user admin_user';
const regex = /(?<!inactive_)\buser/g;
const matches = data.match(regex);
console.log(matches); // Output: ["user", "user"]

Combining Lookbehind Assertions with Capture Groups

Lookbehind assertions can be combined with capture groups to implement more complex matching logic.

const log = 'Error: 404 at 10:30, Warning: 500 at 11:45';
const regex = /(?<=Warning:\s)(\d+).*?at\s(\d+:\d+)/;
const match = log.match(regex);
console.log(match[1]); // Error code: 500
console.log(match[2]); // Time: 11:45

Limitations of Lookbehind Assertions

The pattern inside a lookbehind assertion must have a fixed length. Quantifiers like * or + that result in variable-length patterns are not allowed.

// Invalid lookbehind assertion
const invalidRegex = /(?<=a+)\d/; // Error

Practical Use Cases

  1. Extracting content after a specific prefix:
const config = 'host=localhost port=8080 timeout=30';
const regex = /(?<=\bport=)\d+/;
const port = config.match(regex)[0];
console.log(port); // 8080
  1. Excluding matches with specific prefixes:
const text = 'internal_id:123 external_id:456';
const regex = /(?<!external_)\bid:\d+/g;
const matches = text.match(regex);
console.log(matches); // ["id:123"]
  1. Password strength validation:
function validatePassword(password) {
  // Must contain a digit not preceded by $
  return /(?<!\$)\d/.test(password);
}
console.log(validatePassword('abc123')); // true
console.log(validatePassword('abc$123')); // false

Browser Compatibility Considerations

Although lookbehind assertions are part of the ES2017 standard, browser compatibility must still be considered. As of 2023, all modern browsers support this feature, but older browsers or certain environments may require transpilation.

Feature detection can be used to check for support:

try {
  new RegExp('(?<=a)b');
  console.log('Lookbehind assertions supported');
} catch (e) {
  console.log('Lookbehind assertions not supported');
}

Performance Considerations

Lookbehind assertions generally consume more resources than lookahead assertions, especially when processing long strings. In performance-sensitive scenarios, use lookbehind assertions cautiously or consider alternative implementations.

// Poor performance usage
const slowRegex = /(?<=^.{1000})./;

// Better alternative
const fastRegex = /^.{1000}(.)/;

Combining with Other Regex Features

Lookbehind assertions can be combined with other regular expression features, such as flags and quantifiers.

// Match all commas not inside quotes
const csv = 'a,b,"c,d",e';
const regex = /(?<!["[^"]*),(?![^"]*")/g;
const fields = csv.split(regex);
console.log(fields); // ["a", "b", "\"c,d\"", "e"]

Common Errors and Debugging

Common errors when using lookbehind assertions include variable-length patterns and improper assertion placement. Online regex testing tools can help debug complex expressions step by step.

// Error example: Variable-length pattern
// const errorRegex = /(?<=(a|ab))c/; // Error

// Correct example: Fixed-length pattern
const correctRegex = /(?<=(a|bb))c/;

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.