forked from denoland/std
-
Notifications
You must be signed in to change notification settings - Fork 0
/
is_glob.ts
49 lines (42 loc) · 1.22 KB
/
is_glob.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
/**
* Test whether the given string is a glob.
*
* @example Usage
* ```ts
* import { isGlob } from "@std/path/is-glob";
* import { assert } from "@std/assert";
*
* assert(!isGlob("foo/bar/../baz"));
* assert(isGlob("foo/*ar/../baz"));
* ```
*
* @param str String to test.
* @returns `true` if the given string is a glob, otherwise `false`
*/
export function isGlob(str: string): boolean {
const chars: Record<string, string> = { "{": "}", "(": ")", "[": "]" };
const regex =
/\\(.)|(^!|\*|\?|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
if (str === "") {
return false;
}
let match: RegExpExecArray | null;
while ((match = regex.exec(str))) {
if (match[2]) return true;
let idx = match.index + match[0].length;
// if an open bracket/brace/paren is escaped,
// set the index to the next closing character
const open = match[1];
const close = open ? chars[open] : null;
if (open && close) {
const n = str.indexOf(close, idx);
if (n !== -1) {
idx = n + 1;
}
}
str = str.slice(idx);
}
return false;
}