Skip to main content

Full Find and Replace

Extended tool set for finding and replacing content

@findr/text

@findr/text is the core package for all @findr derived packages, it allows powerfull replacement of plain text. It can be used by libraries to enable searching over all sort of formats like Markdown, USFM, HTML, etc.

Installation​

@findr/text is available as a npm package, install it by running any of the following commands on your terminal:

npm​


pnpm add @findr/text

yarn​


pnpm add @findr/text

pnpm​


pnpm add @findr/text

Walk through​

findr-text is the core module for finding a substring in a given plain-text source. Let's walk through the basics.

The following steps show how to use findr from very basic to more advanced use. While you move forward through the steps the code preview and the UI preview will change, feel free to explore and try to interact with all of it.

For this example we will start with an example function that will be used by our UI to render the results of findr.

example.js

_1
export default function example() {}

1. Add some dummy text​

First lets add some dummy source text to search on.

example.js

_4
export default function example() {
_4
const txt =
_4
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_4
}

2. Add findr​

Now let's add findr in the mix

example.js

_6
import fnr from "@findr/text";
_6
_6
export default function example() {
_6
const txt =
_6
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_6
}

3. Let's use findr​

Finally, let's use finder and pass in some props. You should now get some results.

example.js

_11
import fnr from "@findr/text";
_11
_11
export default function example() {
_11
const txt =
_11
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_11
_11
return fnr({
_11
source: txt,
_11
target: "nostrud",
_11
});
_11
}

As you can see we already have some results, take a look at the results. Now we need to get some context, let's do that.

4. Getting some context​

Pass in a config prop to fnr. ctxLen will tell fnr how much context we want to get around our matched result.

example.js

_14
import fnr from "@findr/text";
_14
_14
export default function example() {
_14
const txt =
_14
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_14
_14
return fnr({
_14
source: txt,
_14
target: "nostrud",
_14
config: {
_14
ctxLen: 20,
_14
},
_14
});
_14
}

Oh, looks like some words sneaked into our results. We only wanted the word "nostrud" not words that contained it.

5. Selecting only whole words​

Let's pass the isWordMatched config param to fnr.

example.js

_15
import fnr from "@findr/text";
_15
_15
export default function example() {
_15
const txt =
_15
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_15
_15
return fnr({
_15
source: txt,
_15
target: "nostrud",
_15
config: {
_15
ctxLen: 20,
_15
isWordMatched: true,
_15
},
_15
});
_15
}

Now we have the right results, but these are matching the casing of our target, we also want to find words that have different casing.

Let's use the isCaseMatched config param.

example.js

_16
import fnr from "@findr/text";
_16
_16
export default function example() {
_16
const txt =
_16
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_16
_16
return fnr({
_16
source: txt,
_16
target: "nostrud",
_16
config: {
_16
ctxLen: 20,
_16
isWordMatched: true,
_16
isCaseMatched: false,
_16
},
_16
});
_16
}

We found two more words, now we can replace them.

7. Replacing​

Let's add a replacement string.

example.js

_17
import fnr from "@findr/text";
_17
_17
export default function example() {
_17
const txt =
_17
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_17
_17
return fnr({
_17
source: txt,
_17
target: "nostrud",
_17
replacement: "my new word",
_17
config: {
_17
ctxLen: 20,
_17
isWordMatched: true,
_17
isCaseMatched: false,
_17
},
_17
});
_17
}

Our UI shows us a preview of how these replacement strings will look like. As you can see, even when the word found starts with an uppercase letter, the replacement result starts with the same case as our replacement input, so let's add a new configuration parameter.

8. Preserving casing​

Let's add the isCasePreserved config param.

example.js

_18
import fnr from "@findr/text";
_18
_18
export default function example() {
_18
const txt =
_18
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_18
_18
return fnr({
_18
source: txt,
_18
target: "nostrud",
_18
replacement: "my new word",
_18
config: {
_18
ctxLen: 20,
_18
isWordMatched: true,
_18
isCaseMatched: false,
_18
isCasePreserved: true,
_18
},
_18
});
_18
}

Now if our match starts with uppercase, the replacement string will also start with uppercase. So far we have not replaced anything, for that we need to pass to findr the list of results we want to replace.

9. Actually replacing​

If you pass replacementKeys to fnr it will replace those results and return a replaced string which contains the whole source string with changes applied to it.

example.js

_19
import fnr from "@findr/text";
_19
_19
export default function example() {
_19
const txt =
_19
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_19
_19
return fnr({
_19
source: txt,
_19
target: "nostrud",
_19
replacement: "my new word",
_19
replacementKeys: [0],
_19
config: {
_19
ctxLen: 20,
_19
isWordMatched: true,
_19
isCaseMatched: false,
_19
isCasePreserved: true,
_19
},
_19
});
_19
}

You can see our list of results got smaller, after passing the resultKeys fnr will return a new list of results, and a new replaced source which you see in the UI by clicking the Replaced tab. Now let's replace all.

10. Replace all​

replacementKeys also accepts a string with a value of "all", let's change it to that.

example.js

_19
import fnr from "@findr/text";
_19
_19
export default function example() {
_19
const txt =
_19
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_19
_19
return fnr({
_19
source: txt,
_19
target: "nostrud",
_19
replacement: "my new word",
_19
replacementKeys: "all",
_19
config: {
_19
ctxLen: 20,
_19
isWordMatched: true,
_19
isCaseMatched: false,
_19
isCasePreserved: true,
_19
},
_19
});
_19
}

You can see now we are getting 0 results. And the replaced tab contains a new source with all our newly replaced content. Now let's go back to our original source and say we wanted to replace all text that is enclosed by the « » characters. For that let's use RegEx.

11. Supporting RegEx​

Let's add a the isRegex config param, and add some RegEx to our target param.

example.js

_19
import fnr from "@findr/text";
_19
_19
export default function example() {
_19
const txt =
_19
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_19
_19
return fnr({
_19
source: txt,
_19
target: "«.+?»",
_19
replacement: "my new word",
_19
config: {
_19
isRegex: true,
_19
ctxLen: 20,
_19
isWordMatched: true,
_19
isCaseMatched: false,
_19
isCasePreserved: true,
_19
},
_19
});
_19
}

Excellent, we've now found all text that is surrounded by « and », let's say we wanted to keep that inner text but remove the surrounding characters, for that let's use replacement patterns, and change our target prop a little to store the part we want to keep.

12. Using replacement patterns​

We surrounded with parentheses the part of the Regex we want to store, and then for the prop replacement we changed it to $1 ro refer to the first (and only) stored part of the Regex.

example.js

_19
import fnr from "@findr/text";
_19
_19
export default function example() {
_19
const txt =
_19
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_19
_19
return fnr({
_19
source: txt,
_19
target: "«(.+?)»",
_19
replacement: "$1",
_19
config: {
_19
isRegex: true,
_19
ctxLen: 20,
_19
isWordMatched: true,
_19
isCaseMatched: false,
_19
isCasePreserved: true,
_19
},
_19
});
_19
}

Great! Fnr stored every string that matched the Regex expression in parentheses and we were able to access that by using $1.

This covers all the basic features and a little more . If you need more, there is an API you can look at. You can play with this example yourself on our codesandbox: https://codesandbox.io/s/findr-text-c9juk6

The following steps show how to use findr from very basic to more advanced use. While you move forward through the steps the code preview and the UI preview will change, feel free to explore and try to interact with all of it.

For this example we will start with an example function that will be used by our UI to render the results of findr.

1. Add some dummy text​

First lets add some dummy source text to search on.

2. Add findr​

Now let's add findr in the mix

3. Let's use findr​

Finally, let's use finder and pass in some props. You should now get some results.

As you can see we already have some results, take a look at the results. Now we need to get some context, let's do that.

4. Getting some context​

Pass in a config prop to fnr. ctxLen will tell fnr how much context we want to get around our matched result.

Oh, looks like some words sneaked into our results. We only wanted the word "nostrud" not words that contained it.

5. Selecting only whole words​

Let's pass the isWordMatched config param to fnr.

Now we have the right results, but these are matching the casing of our target, we also want to find words that have different casing.

Let's use the isCaseMatched config param.

We found two more words, now we can replace them.

7. Replacing​

Let's add a replacement string.

Our UI shows us a preview of how these replacement strings will look like. As you can see, even when the word found starts with an uppercase letter, the replacement result starts with the same case as our replacement input, so let's add a new configuration parameter.

8. Preserving casing​

Let's add the isCasePreserved config param.

Now if our match starts with uppercase, the replacement string will also start with uppercase. So far we have not replaced anything, for that we need to pass to findr the list of results we want to replace.

9. Actually replacing​

If you pass replacementKeys to fnr it will replace those results and return a replaced string which contains the whole source string with changes applied to it.

You can see our list of results got smaller, after passing the resultKeys fnr will return a new list of results, and a new replaced source which you see in the UI by clicking the Replaced tab. Now let's replace all.

10. Replace all​

replacementKeys also accepts a string with a value of "all", let's change it to that.

You can see now we are getting 0 results. And the replaced tab contains a new source with all our newly replaced content. Now let's go back to our original source and say we wanted to replace all text that is enclosed by the « » characters. For that let's use RegEx.

11. Supporting RegEx​

Let's add a the isRegex config param, and add some RegEx to our target param.

Excellent, we've now found all text that is surrounded by « and », let's say we wanted to keep that inner text but remove the surrounding characters, for that let's use replacement patterns, and change our target prop a little to store the part we want to keep.

12. Using replacement patterns​

We surrounded with parentheses the part of the Regex we want to store, and then for the prop replacement we changed it to $1 ro refer to the first (and only) stored part of the Regex.

Great! Fnr stored every string that matched the Regex expression in parentheses and we were able to access that by using $1.

This covers all the basic features and a little more . If you need more, there is an API you can look at. You can play with this example yourself on our codesandbox: https://codesandbox.io/s/findr-text-c9juk6

example.js
ExpandClose

_4
export default function example() {
_4
const txt =
_4
"Consequat officia nisi «nostrud» ea nisi. «Ullamco consequat» velit consectetur ea velit sunt exercitation. Ipsum in minostrud «magna dolor». Do aliquip do minim excepteur pariatur excepteur qui. Consectetur dolore magna id elit. Nostrud officia sint pariatur nisi deserunt. Labore sunt est dolor fugiat nostrudquis ut incididunt proident nisi velit exercitation. Nostrud deserunt!";
_4
}