Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way to run the replace on only the first match? #45

Open
jacobedawson opened this issue Aug 7, 2019 · 3 comments
Open

Comments

@jacobedawson
Copy link

jacobedawson commented Aug 7, 2019

Thanks for a very cool function! What I'm trying to do is replace a user selected string in a body of text with a React component (that contains the selected string). The issue I'm running into is that react-string-replace is replacing all instances of a selection, rather than just the first match.

Since I'm targeting user-selected text (via the Selection API), I'm using a RegExp constructor, like so:

const key = uuid(); // generate unique key
const textRegex = new RegExp(`(${window.getSelection().toString()})`); // capture user selection
const updatedText = ReactStringReplace(postText, textRegex, match => {
  return <HighlightSpan text={match} key={key} />; // return React component
});
// other stuff

This works absolutely perfectly if the selected string is unique in the body of text, but if there is another match then I run into a duplicate key error (and also highlight multiple selections when I only want the first).

Since the RegExp constructor doesn't include a 'g' flag, as far as I understand it should only match the first occurrence - but I might be mistaken as to how react-string-replace works! Is it possible to have it run only once, and if so could you please give me a tip on how to achieve this?

Thanks in advance,

Jake

EDIT

Just actually checked the code and realized that the g & i flags are set by default - perhaps I could make a pull request to have the regex flags optional?

@iansinnott
Copy link
Owner

Hey @jacobedawson, those flags should only be set if you don't supply your own regex, so I don't think that's the issue.

I'd guess you're running into the behavior of str.split. It will split on every match with or without regex flags. Run this in the console to see what I mean:

'hey there\nthis is a new line'.split(/( )/)

split does support a second limit argument which you might be able to use to your advantage here. I'd recommend trying that approach (either without this lib or with a fork) and seeing where you end up.

If you have a way to incorporate this into the lib that would be great too!

@jacobedawson
Copy link
Author

Hey @iansinnott thanks man, yeah I dug a bit further and saw that the flags were only set on !isRegExp(match), I've adapted the function in my project as I'm on a deadline but if I have some spare time I'll make a pull request - after a lot of searching your package finally put me on the right track!

Thanks for making FOSS :)

@kieransimkin
Copy link

kieransimkin commented Feb 23, 2024

I have now created a PR for this change: #91

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants