-
Notifications
You must be signed in to change notification settings - Fork 55
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
Trouble formatting bold/italic/underline text with capture group regex #33
Comments
Hey @CaptainStiggz, yeah this lib does not handle nested replacements. The reason being, it's meant to be roughly equivalent to If you look here you'll see that it only runs replacements on strings. Once your first replacement has been run the element in the result array will be an object (i.e. I'm open to suggestions if you have thoughts about how we might support more robust replacements. To your second point, it just depends on the regex. If you can craft a regex that handles unbalanced/malformed tags then it should work fine. But there's no internal logic here to augment the functionality of the regex. |
Thanks @iansinnott! I've been fooling around with a recurisive augmentation as follows. It's still pretty rough, but it might be useful. This modification, combined with a slight modification to the regex I originally suggested ( const reactStringReplaceRecursive = (input, pattern, fn, key=0) => {
const isEmpty = (item) => {
if(!item) return true
if(item.hasOwnProperty('props')) {
return false
} else {
return (item.length) ? false : true
}
}
if(!input) {
return null
} else if(typeof input === "string") {
return reactStringReplace(input, pattern, fn)
}
var output = []
for(var i=0; i<input.length; i++) {
const item = input[i]
if(item) {
if(typeof item === "string") {
const next = reactStringReplace(item, pattern, fn)
if(!isEmpty(next)) output.push(next)
} else if(typeof item === "object") {
if(item.hasOwnProperty('props') && item.props.hasOwnProperty('children')) {
const next = reactStringReplaceRecursive(item.props.children, pattern, fn, key+1)
if(!isEmpty(next)) {
const props = Object.assign({key: "k"+key+"i"+i}, item.props)
output.push(React.createElement(
item.type,
props,
next
))
}
} else {
const next = reactStringReplaceRecursive(item, pattern, fn, key+1)
if(!isEmpty(next)) output.push(next)
}
}
}
}
return output
} This is a decent start, but still runs into some troublesome edge cases. For example, depending on the ordering of the bold/italic tags, I might end up with something like this: const text = "[i][b]this should be bold and italic[/b][/i]"
// const text = "[b][i]this should be bold and italic[/i][/b]" - this would work
let replaced = reactStringReplace(text, /\[b\]([\s\S]+?)\[\/b\]/g, (match, i) => {
return <b key={i}>{match}</b>
})
replaced = reactStringReplace(replaced, /\[i\]([\s\S]+?)\[\/i\]/g, (match, i) => {
return <i key={i}>{match}</i>
})
// replaced => [
// "[i]",
// <b>this should be bold and italic</b>,
// "[/i]"
// ] The problem gets pretty tricky here. Not exactly sure how I want to handle such cases. |
You might consider using the That being said, you're use case is essentially a new rich text markup, which might be beyond the scope of simple regex and string replacement. You might consider using a stack to help you track opening/closing brackets and build up a deeply nested data structure representing your markup. Or do something like DraftJS does and annotate each character in the string with metadata which you subsequently use to render the markup. In either case you'll probably end up having to revert to strings and DraftJS character metadata: https://draftjs.org/docs/api-reference-character-metadata.html |
I'm having trouble using
reactStringReplace
to format text with bold/italic tags. I have it set up as follows:I'm not sure if this is a problem with
reactStringReplace
, with the regex I'm using, or something else. If I apply the italic replace first, I get italic tags where I'd expect them to be, but the [b] tags remain unchanged. Is this use case possible usingreactStringReplace
or do I need to usedangerouslySetInnerHtml
?Bonus: is
reactStringReplace
capable of handling unbalanced tags, or improperly formatted tags as intext2
or should I be doing some pre-processing to ensure the strings are properly balanced and formatted?The text was updated successfully, but these errors were encountered: