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

add example using curly braces in replacement string #333

Closed
lilith opened this issue Jan 24, 2017 · 3 comments · Fixed by #343
Closed

add example using curly braces in replacement string #333

lilith opened this issue Jan 24, 2017 · 3 comments · Fixed by #343
Assignees
Labels

Comments

@lilith
Copy link

lilith commented Jan 24, 2017

This used to work:
assert_eq!(Regex::new("(.)").unwrap().replace_all("a", "$1_"), "a_" );

But now produces "" instead of "a_".

It would appear that underscores somehow cause the replacement to be deleted instead of added.

Named captures don't fix it:

assert_eq!(Regex::new("(?P<char>.)").unwrap().replace_all("a", "$char_"), "a_" ); //actual: ""

But inserting a space between the capture and underscore works!

assert_eq!(Regex::new("(.)").unwrap().replace_all("a", "$1 _"), "a _" );
assert_eq!(Regex::new("(?P<char>.)").unwrap().replace_all("a", "$char _"), "a _" );

As does using curly braces around the identifier (the only apparent workaround)

assert_eq!(Regex::new("(?P<char>.)").unwrap().replace_all("a", "${char}_"), "a_" );

@BurntSushi
Copy link
Member

This was an intended but undocumented breaking change. Note the docs for expand say:

name may be an integer corresponding to the index of the capture group (counted by order of opening parenthesis where 0 is the entire match) or it can be a name (consisting of letters, digits or underscores) corresponding to a named capture group.

and also

The longest possible name is used. e.g., $1a looks up the capture group named 1a and not the capture group at index 1. To exert more precise control over the name, use braces, e.g., ${1}a.

So this means that the reason why you're getting the behavior you see is that 1_ is used as the capture group name, and since that doesn't refer to any valid capture, it is replaced with the empty string. Indeed, the fix is to use curly braces.

@BurntSushi BurntSushi added the doc label Jan 24, 2017
@BurntSushi BurntSushi self-assigned this Jan 24, 2017
@lilith
Copy link
Author

lilith commented Jan 25, 2017

Ah. I was hoping that replacements would only expand if existent in the original regex.

It'd probably be good to emphasize this, and stick to the curly brace syntax for examples. I'm not aware of other regex implementations with this behavior, thus my confusion :)

I tend to expect that identifiers don't start with numbers.

@BurntSushi
Copy link
Member

@nathanaeljones Go's regexp engine has precisely the same semantics. But yes, better docs here would be great.

@BurntSushi BurntSushi changed the title Possible 0.2.1 regression in replacement strings add example using curly braces in replacement string Feb 18, 2017
BurntSushi added a commit to BurntSushi/regex that referenced this issue Feb 18, 2017
This shows how to use curly braces in the replacement string, and more
specifically, explains why they are sometimes necessary.

Fixes rust-lang#333
@BurntSushi BurntSushi mentioned this issue Feb 18, 2017
bors added a commit that referenced this issue Feb 18, 2017
Fixes

This PR contains a series of commits that fixes several minor bugs.

Fixes #321, Fixes #334, Fixes #326, Fixes #333, Fixes #338
@bors bors closed this as completed in #343 Feb 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants