S
SolidJS12mo ago
Grahf

Replace part of string with a component

I found this for react: https://github.com/iansinnott/react-string-replace It seems to be able to replace a part of a string with the results of a component? That's what it looks like to me. I haven't used it.
Just wondering if anyone has done anything similar with solidJS. It's probably pretty niche.
GitHub
GitHub - iansinnott/react-string-replace: A simple way to safely do...
A simple way to safely do string replacement with React components - GitHub - iansinnott/react-string-replace: A simple way to safely do string replacement with React components
16 Replies
REEEEE
REEEEE12mo ago
Should be fairly easy to implement using Dynamic or just regular jsx i think
Grahf
Grahf12mo ago
Say you wanted to replace the text in a string everytime it matched this: (“|")[^(”|")]+(”|")[⁰¹²³⁴⁵⁶⁷⁸⁹]+|[⁰¹²³⁴⁵⁶⁷⁸⁹]+|\S+[⁰¹²³⁴⁵⁶⁷⁸⁹]+ Otherwise leave the string unchanged replace it with a component
Edivado
Edivado12mo ago
StackBlitz
Solid-start Bare Example (forked) - StackBlitz
Run official live example code for Solid-start Bare, created by Solidjs on StackBlitz
Grahf
Grahf12mo ago
I can't get the stackBlitz to load.... has been installing dependencies for minutes. But you just installed react-string-replace and it worked?
Edivado
Edivado12mo ago
yeah but depending on your setup if you are using typescript it may complain about type definitions
Grahf
Grahf12mo ago
I hate to be that guy but I don't like to use things that come from Microsoft. But I do use typescript at work. But it wont be in my personal projects
Edivado
Edivado12mo ago
Then it should just work. I made another stackblitz maybe this opens. https://stackblitz.com/edit/solidjs-solid-start-egeuoa?file=src%2Froutes%2Findex.tsx
Grahf
Grahf12mo ago
I have it in a <For> loop that loops through some regex matches and getting some very strrange results. May too much text. It's repeting parts of the text. Going to try to get rid of <For> loop docs for it even have a section titled: Multiple replacements on a single string So cool This regex normally grabs certain text. It selects the right things in a sepaarte JS program and on regex playgrounds. /(“|")[^(”|")]+(”|")[⁰¹²³⁴⁵⁶⁷⁸⁹]+|[⁰¹²³⁴⁵⁶⁷⁸⁹]+|\S+[⁰¹²³⁴⁵⁶⁷⁸⁹]+/gm But this react-string-replace grabs different text with it
Edivado
Edivado12mo ago
Do you have some sample text I could try your regex on?
Grahf
Grahf12mo ago
https://regex101.com/r/g6W14s/1 part of my code:
{reactStringReplace(
props.text,
/(“|")[^(”|")]+(”|")[⁰¹²³⁴⁵⁶⁷⁸⁹]+|[⁰¹²³⁴⁵⁶⁷⁸⁹]+|\S+[⁰¹²³⁴⁵⁶⁷⁸⁹]+/gm,
{reactStringReplace(
props.text,
/(“|")[^(”|")]+(”|")[⁰¹²³⁴⁵⁶⁷⁸⁹]+|[⁰¹²³⁴⁵⁶⁷⁸⁹]+|\S+[⁰¹²³⁴⁵⁶⁷⁸⁹]+/gm,
Edivado
Edivado12mo ago
to me that looks like an issue with the lib i tried it with my own incomplete implementation of replace and that one seems to work In case you want to try here:
function regReplaceWithComponent(
text: string,
exp: RegExp,
fn: (match: string, index: number) => JSXElement
) {
const matches = [...text.matchAll(exp)];
if (!matches.length) return text;
return matches.reduce((items, match, index, matches) => {
const offset = index
? matches[index - 1].index! + matches[index - 1][0].length
: 0;

items.push(text.slice(offset, match.index));
items.push(fn(match[0], index));

if (
index === matches.length - 1 &&
match.index! + match[0].length < text.length
) {
items.push(text.slice(match.index! + match[0].length));
}

return items;
}, [] as JSXElement[]);
}
function regReplaceWithComponent(
text: string,
exp: RegExp,
fn: (match: string, index: number) => JSXElement
) {
const matches = [...text.matchAll(exp)];
if (!matches.length) return text;
return matches.reduce((items, match, index, matches) => {
const offset = index
? matches[index - 1].index! + matches[index - 1][0].length
: 0;

items.push(text.slice(offset, match.index));
items.push(fn(match[0], index));

if (
index === matches.length - 1 &&
match.index! + match[0].length < text.length
) {
items.push(text.slice(match.index! + match[0].length));
}

return items;
}, [] as JSXElement[]);
}
Does not handle all edge cases and match.index could be undefined just for testing
Grahf
Grahf12mo ago
ok wow that's amazing my head hurts. I've been trying to split the string at the right spots and piece it back together with the component in the right place for a while. It's dark where I'm at in the world. Going to get a little rest and try again tomorrow. What you wrote looks really promising. Wish I could think through this as fast as you did to come up with at least an approximate solution. Thanks And something else I just thought of was using string.match to get all the regex matches and then feeding those matches to this third-party tool Maybe But then I'd be back to using a loop and it wasn't working out well with the loop before
Edivado
Edivado12mo ago
Have a good rest I guess you would have to test your regex against split and play by its rules because that is what it's using internally.
Grahf
Grahf12mo ago
Hey thanks I've been trying to wrap my head around this. Even though I don't totally understand it it seems to work for my purposes. I might make some small changes as I start to understand it. If you have a github/gitlab I'd like to put a note about this code in my repo saying that you wrote it. Or I can just mention your discord name
Edivado
Edivado12mo ago
Its fine no need to. Out of my own curiosity I took a closer look at the libs implementation. I don't understand why it would use split instead of matchAll after reading about splits behaviour with capturing groups. I made a small gist with matchAll. https://gist.github.com/edivados/0b24fd7e876d1940fd273361a31ffe1c (you have to use g flag with matchAll)
Gist
regReplaceWithComponent.ts
GitHub Gist: instantly share code, notes, and snippets.
thetarnav
thetarnav12mo ago
GitHub
solid-primitives/packages/marker at main · solidjs-community/solid-...
A library of high-quality primitives that extend SolidJS reactivity. - solidjs-community/solid-primitives