Skip to content

Commit

Permalink
feat(string): add strReplace fn
Browse files Browse the repository at this point in the history
  • Loading branch information
Thanga-Ganapathy committed Mar 16, 2024
1 parent d8e5e77 commit bdbf93b
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-phones-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@opentf/utils": minor
---

Added strReplace fn.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ await sleep(1000); // It suspends the exection for 1 second.
- [isEmail](https://js-utils.pages.dev/docs/String/isEmail)
- [pascalCase](https://js-utils.pages.dev/docs/String/pascalCase)
- [replaceAt](https://js-utils.pages.dev/docs/String/replaceAt)
- [strReplace](https://js-utils.pages.dev/docs/String/strReplace)

### Types

Expand Down
3 changes: 2 additions & 1 deletion apps/docs/pages/String/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"insertAt": "insertAt",
"isEmail": "isEmail",
"pascalCase": "pascalCase",
"replaceAt": "replaceAt"
"replaceAt": "replaceAt",
"strReplace": "strReplace"
}
59 changes: 59 additions & 0 deletions apps/docs/pages/String/strReplace.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Returns a new string with one, some, or all matches of a pattern replaced by a replacement.
## Syntax

```ts
import { strReplace } from '@opentf/utils';

strReplace(str: string,
pattern: string | RegExp,
replacement: string | Function,
options: {all: boolean, case: boolean}
): string;
```

<Callout type="info">
The replacement function can be in the form of [specifying_a_function_as_the_replacement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_function_as_the_replacement)
</Callout>

<Callout type="info">
- The option `all` refers to RegExp `g` global flag.
- The option `case` refers to RegExp `i` ignore case / case insensitive flag.
</Callout>

## Examples

```ts
strReplace('abc', 'a', 'x') //=> 'xbc'

strReplace('abbc', 'b', '', { all: true }) //=> 'ac'

strReplace('aBbBc', 'B', '', { all: true, case: true }) //=> 'ac'

const paragraph = "I think Ruth's dog is cuter than your dog!";
const regex = /dog/;
strReplace(paragraph, regex, 'ferret') //=> "I think Ruth's ferret is cuter than your dog!"

const str = 'Twas the night before Xmas...';
strReplace(str, /xmas/, 'Christmas', { case: true }) //=> 'Twas the night before Christmas...'

const str = 'Apples are round, and apples are juicy.';
strReplace(str, /apple/, 'Orange', { all: true, case: true }) //=> 'Oranges are round, and Oranges are juicy.'

function convert(str, p1) {
return `${((p1 - 32) * 5) / 9}C`;
}
const test = /(-?\d+(?:\.\d*)?)F\b/;
strReplace('212F', test, convert) //=> '100C'
```

## Try

<REPL code={`const { strReplace } = require('@opentf/utils');
const str = 'Apples are round, and apples are juicy.';
strReplace(str, 'apple', 'orange');
`} />
5 changes: 5 additions & 0 deletions apps/docs/pages/Types/isPureObj.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Callout } from "nextra/components";
import REPL from "../../components/REPL";

> Checks if the given value is an [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) and not null.
<Callout type="info">
In JavaScript `typeof null` is `'object'`.
</Callout>

## Syntax

```ts
Expand Down
1 change: 1 addition & 0 deletions packages/utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ await sleep(1000); // It suspends the exection for 1 second.
- [isEmail](https://js-utils.pages.dev/docs/String/isEmail)
- [pascalCase](https://js-utils.pages.dev/docs/String/pascalCase)
- [replaceAt](https://js-utils.pages.dev/docs/String/replaceAt)
- [strReplace](https://js-utils.pages.dev/docs/String/strReplace)

### Types

Expand Down
54 changes: 54 additions & 0 deletions packages/utils/__tests__/string/strReplace.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { strReplace } from '../../src';

describe('String > strReplace', () => {
test('invalid replace', () => {
expect(strReplace('abc', null, 'x')).toBe('abc');
expect(strReplace('abc', 'a', null)).toBe('nullbc');
});

test('single replace', () => {
expect(strReplace('abc', 'a', 'x')).toBe('xbc');
});

test('multi replace', () => {
expect(strReplace('abbc', 'b', '', { all: true })).toBe('ac');
expect(strReplace('aBbBc', 'B', '', { all: true, case: true })).toBe('ac');
});

test('regexp replace', () => {
const paragraph = "I think Ruth's dog is cuter than your dog!";
const regex = /dog/;
expect(strReplace(paragraph, regex, 'ferret')).toBe(
"I think Ruth's ferret is cuter than your dog!"
);
});

test('regexp replace with ignore case', () => {
const str = 'Twas the night before Xmas...';
expect(strReplace(str, /xmas/, 'Christmas', { case: true })).toBe(
'Twas the night before Christmas...'
);
});

test('regexp replace with global', () => {
const str = 'Apples are round, and apples are juicy.';
expect(strReplace(str, /apple/, 'orange', { all: true })).toBe(
'Apples are round, and oranges are juicy.'
);
});

test('regexp replace with global & ignore case', () => {
const str = 'Apples are round, and apples are juicy.';
expect(strReplace(str, /apple/, 'Orange', { all: true, case: true })).toBe(
'Oranges are round, and Oranges are juicy.'
);
});

test('Replacement fn', () => {
function convert(str, p1) {
return `${((p1 - 32) * 5) / 9}C`;
}
const test = /(-?\d+(?:\.\d*)?)F\b/;
expect(strReplace('212F', test, convert)).toBe('100C');
});
});
10 changes: 9 additions & 1 deletion packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"js",
"ts",
"utils",
"utility",
"string",
"array",
"object",
Expand All @@ -24,7 +25,14 @@
"shallow",
"deep",
"case",
"assert"
"assert",
"replace",
"diff",
"range",
"sort",
"merge",
"zero",
"neg"
],
"author": {
"name": "Thanga Ganapathy",
Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { default as insertAt } from './string/insertAt';
export { default as capitalize } from './string/capitalize';
export { default as camelCase } from './string/camelCase';
export { default as pascalCase } from './string/pascalCase';
export { default as strReplace } from './string/strReplace';

// Array
export { default as arrDiff } from './array/arrDiff';
Expand Down
26 changes: 26 additions & 0 deletions packages/utils/src/string/strReplace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import shallowMerge from '../object/shallowMerge';

export type StrReplaceOptions = { all?: boolean; case?: boolean };

/**
* Returns a new string with one, some, or all matches of a pattern replaced by a replacement.
*
* @example
* const a = { a: { b: 1 } };
* const b = { a: { c: 2 } };
* merge(a, b); //=> {a: { b: 1, c: 2 } }
*/
export default function strReplace(
str: string,
pattern: string | RegExp,
replacement: string,
options: StrReplaceOptions
) {
const defaultOptions: StrReplaceOptions = { all: false, case: false };
const opts = shallowMerge(defaultOptions, options) as StrReplaceOptions;
let flags = '';
flags = opts.all ? flags + 'g' : flags;
flags = opts.case ? flags + 'i' : flags;

return str.replace(new RegExp(pattern, flags), replacement);
}

0 comments on commit bdbf93b

Please sign in to comment.