std/path/is_glob.ts

50 lines
1.2 KiB
TypeScript

// 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;
}