diff --git a/docs/methods.md b/docs/methods.md index 741a10b..546a3b3 100644 --- a/docs/methods.md +++ b/docs/methods.md @@ -98,6 +98,7 @@ - [wordWrap](#wordwrap) - [words](#words) - [wrap](#wrap) +- [unwrap](#unwrap) - [value](#value) ## Fluent Strings @@ -374,7 +375,7 @@ Stringable.of('{first: "John", last: "Doe"}').isJson(); ### isUrl The `isUrl` method determines if a given string is a valid URL: ```js -Stringable.of('http://example.com').isUrl(); +Stringable.of('https://example.com').isUrl(); // true @@ -1040,6 +1041,13 @@ Stringable.of('is').wrap('This ', ' me!'); // 'This is me!' ``` +### unwrap +The `unwrap` method removes the specified strings from the beginning and end of a given string: +```js +Stringable.of('-Laravel-').unwrap('- '); + +// 'Laravel' +``` ### value The `value` method returns the underlying string value. ```js diff --git a/docs/statics.md b/docs/statics.md index 049bbd3..dede2de 100644 --- a/docs/statics.md +++ b/docs/statics.md @@ -66,6 +66,7 @@ - [wordWrap](#wordwrap) - [words](#words) - [wrap](#wrap) +- [unwrap](#unwrap) - [preg_quote](#preg_quote) - [random](#random) - [createRandomStringsUsing](#createrandomstringsusing) @@ -230,6 +231,13 @@ Str.wrap('is', 'This ', ' me!'); // 'This is me!' ``` +### unwrap +The `unwrap` function removes the specified strings from the beginning and end of a given string: +```js +Str.unwrap('-Laravel-', '- '); + +// 'Laravel' +``` ### is The `is` function determines if a given string matches a given pattern. Asterisks may be used as wildcard values ```js diff --git a/src/Str.ts b/src/Str.ts index 3b35ac4..c910e1d 100644 --- a/src/Str.ts +++ b/src/Str.ts @@ -61,6 +61,7 @@ import { wordCount, wordWrap, preg_quote, + unwrap, ExcerptOptions, } from './methods'; import Stringable from './Stringable'; @@ -294,6 +295,7 @@ export const Str = { return Stringable.of(ulid()); }, preg_quote, + unwrap, flushCache(): void { this._camelCache = {}; this._snakeCache = {}; diff --git a/src/Stringable.ts b/src/Stringable.ts index ba7fdc7..9cdd02e 100644 --- a/src/Stringable.ts +++ b/src/Stringable.ts @@ -608,6 +608,12 @@ export class Stringable { return this; } + public unwrap = (before: string, after?: string): this => { + this._value = Str.unwrap(this._value, before, after); + + return this; + } + public toHtmlString = (): Element | Node | null => { const template = document.createElement('template'); diff --git a/src/methods.ts b/src/methods.ts index 1a36312..895b12d 100644 --- a/src/methods.ts +++ b/src/methods.ts @@ -641,6 +641,18 @@ export const ucsplit = (string: string): Array => { return string.split(/(?=\p{Lu})/u).map(i => i.trim()); } +export const unwrap = (value: string, before: string, after?: string): string => { + if (value.startsWith(before)) { + value = value.substring(before.length); + } + + if (value.endsWith(after ??= before)) { + value = value.slice(0, -after.length); + } + + return value; +} + export const wordCount = (value: string): number => { return value.trim().split(/\s+/).length; } diff --git a/tests/unwrap.test.js b/tests/unwrap.test.js new file mode 100644 index 0000000..f55a2bd --- /dev/null +++ b/tests/unwrap.test.js @@ -0,0 +1,34 @@ +'use strict'; + +const {Stringable} = require('../src/Stringable'); +const {Str} = require('../src/Str'); +const {unwrap} = require('../src/methods'); + +it('returns an unwrapped string', () => { + expect(Stringable.of('-Laravel-').unwrap('-').toString()) + .toBe('Laravel'); + + expect(Stringable.of('{framework: "Laravel"}').unwrap('{', '}').toString()) + .toBe('framework: "Laravel"'); + + expect(Stringable.of('"value').unwrap('"').toString()) + .toBe('value'); + + expect(Stringable.of('value"').unwrap('"').toString()) + .toBe('value'); + + expect(Stringable.of('foo-bar-baz').unwrap('foo-', '-baz').toString()) + .toBe('bar'); + + expect(Stringable.of('{some: "json"}').unwrap('{', '}').toString()) + .toBe('some: "json"'); + + expect(Stringable.of('"value"').unwrap('"').toString()) + .toBe('value'); + + expect(Str.unwrap('"value"', '"')) + .toBe('value'); + + expect(unwrap('"value"', '"')) + .toBe('value'); +});