> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/js/val/builtin/regex/pattern/lookaround.md).

# lookaround

[JS](/web/js.md) ⟩ [value](/web/js/val.md) ⟩ [object](/web/js/val/obj.md) ⟩ [regex](/web/js/val/builtin/regex.md) ⟩ [pattern](/web/js/val/builtin/regex/pattern.md) ⟩ lookaround

{% hint style="success" %}

```javascript
(?=...)	    // Positive lookahead (match the position before the specified regex)
(?!...)	    // Negative lookahead (don’t match, as above)
(?<=...)    // Positive lookbehind (match the position after the specified regex)
(?<!...)    // Negative lookbehind (don't match, as above)    
```

{% endhint %}

{% tabs %}
{% tab title="📗 參考" %}

* [ ] JS.info ⟩ [Lookahead & lookbehind](https://javascript.info/regexp-lookahead-lookbehind)
* [ ] [Regular Expression Quick Reference](http://regexrenamer.sourceforge.net/help/regex_quickref.html)
  {% endtab %}

{% tab title="📘 手冊" %}
\*
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="JS" %}

```javascript
const {log} = console;

/*
  Symbols
  -------
  • ? : lookaround
  • = : positive
  • ! : negative (NOT)
  • < : lookbehind

  lookahead: X(?=Y)
  ------------------
  match X (followed "immediately" by Y): 
  match X ("lookahead" for Y)
  
  lookahead: X(?=Y)(?=Z)
  -----------------------
  match X (followed "immediately" by Y & Z)
  match X ("lookahead" for Y & Z)
  
  negative lookahead: X(?!Y)
  ---------------------------
  match X (NOT followed "immediately" by Y)
  match X ("negative lookahead" for Y)
  
  Lookbehind: (?<=Y)X
  --------------------
  match X ("immediately" following Y)

  Negative Lookbehind: (?<!Y)X
  -----------------------------
  match X (NOT "immediately" following Y)
*/

//          ↱ space        ╭╮
let str = "1 turkey costs $30€";
//          ╰──── .*30 ─────╯

[
  // lookahead
  // ----------
  //         ╭X╮   Y
  str.match(/\d+(?=€)/),            // ["30"]
  
  //         ╭X╮   ╭╮    ╭──╮
  str.match(/\d+(?=\s)(?=.*30)/),   // ["1"]
  str.match(/\d+(?=.*30)(?=\s)/),   // ["1"]
  
  str.match(/\d+(?=30)(?=\s)/),     // ⭐️ null 
  // (no digits are followed "immediately" by "30")
  
  // negative lookahead
  // ------------------
  str.match(/\d+\b(?!€)/g),         // ["1"]
  //         ╰─╯╰╯   ↑
  
  // lookbehind: 
  // ----------
  //  escaped $ ➞╭╮ ╭─╮
  str.match(/(?<=\$)\d+/),          // ["30"]
  
].forEach(x => log(x))
```

{% endtab %}

{% tab title="💾 程式" %}

* codepen ⟩ [regex: lookaround](https://codepen.io/lochiwei/pen/eYEppJW?editors=0012)
* codewars ⟩ [Regex Password Validation](https://www.codewars.com/kata/52e1476c8147a7547a000811/train/javascript)
  {% endtab %}

{% tab title="📗 參考" %}

* [x] RegExr ⟩ [Password Validation](https://regexr.com/3bfsi)
  {% endtab %}

{% tab title="🗣 討論" %}

* [RegEx to make sure that the string contains at least one lower case char, upper case char, digit and symbol](https://stackoverflow.com/questions/1559751/regex-to-make-sure-that-the-string-contains-at-least-one-lower-case-char-upper)

```javascript
(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)
```

{% endtab %}
{% endtabs %}

## examples

### Password Validation

```javascript
// Look ahead
// -----------
// (?=.*\d)       : at least one digit.
// (?=.*[a-z])    : at least one lower case.
// (?=.*[A-Z])    : at least one upper case.
// [0-9a-zA-Z]{6,}: at least 6 alphanumeric characters.
// /^...$/        : whole line
function validate(password) {
  return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{6,}$/.test(password);
}
```

### words with (-) or (')

{% tabs %}
{% tab title="regex" %}

```javascript
// (?=[a-zA-Z'-]*[a-zA-Z]): at least one alphabet character
// 
/(?=[a-zA-Z'-]*[a-zA-Z])[a-zA-Z'-]+/g
```

{% endtab %}

{% tab title="💾 程式" %}

* RegEx ⟩ [words with (-) and (')](https://regexr.com/67k4i)
  {% endtab %}

{% tab title="🗣 討論" %}

* [Regex to match words with hyphens and/or apostrophes](https://stackoverflow.com/questions/31910955/regex-to-match-words-with-hyphens-and-or-apostrophes)
  {% endtab %}
  {% endtabs %}
