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 docs for SubstitutionString #27134

Merged
merged 7 commits into from
Jun 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export
StridedVector,
SubArray,
SubString,
SubstitutionString,
Timer,
UnitRange,
Val,
Expand Down
33 changes: 33 additions & 0 deletions base/regex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,25 @@ findnext(r::Regex, s::AbstractString, idx::Integer) = throw(ArgumentError(
))
findfirst(r::Regex, s::AbstractString) = findnext(r,s,firstindex(s))

"""
SubstitutionString(substr)

Stores the given string `substr` as a `SubstitutionString`, for use in regular expression
substitutions. Most commonly constructed using the [`@s_str`](@ref) macro.

```jldoctest
julia> SubstitutionString("Hello \\\\g<name>, it's \\\\1")
s"Hello \\\\g<name>, it's \\\\1"

julia> subst = s"Hello \\g<name>, it's \\1"
s"Hello \\\\g<name>, it's \\\\1"

julia> typeof(subst)
SubstitutionString{String}

```

"""
struct SubstitutionString{T<:AbstractString} <: AbstractString
string::T
end
Expand All @@ -245,6 +264,20 @@ function show(io::IO, s::SubstitutionString)
show(io, s.string)
end

"""
@s_str -> SubstitutionString

Construct a substitution string, used for regular expression substitutions. Within the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to escape all the backslashes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've corrected that and fixed some doc reference errors (thanks to help from @fredrikekre), committed that to the PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually you need single backslashes; the examples don't work with double ones. That's because non-standard string literal macros are passed the raw string, and escapes are not interpreted.

Copy link
Member

@KristofferC KristofferC May 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example is inside a julia string and escapes are interpreted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I chose the wrong thread. My comment applies to uses of s"..." below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where? Everything here is inside a normal julia string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@KristofferC KristofferC May 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it won't have double slashes in the rendered documentation? Again, because this is inside a normal julia string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahah, got it, that's tricky. Indeed that's a special string inside a standard (doc)string...

string, sequences of the form `\\N` refer to the Nth capture group in the regex, and
`\\g<groupname>` refers to a named capture group with name `groupname`.

```jldoctest
julia> msg = "#Hello# from Julia";

julia> replace(msg, r"#(.+)# from (?<from>\\w+)" => s"FROM: \\g<from>; MESSAGE: \\1")
"FROM: Julia; MESSAGE: Hello"
```
"""
macro s_str(string) SubstitutionString(string) end

replace_err(repl) = error("Bad replacement string: $repl")
Expand Down
5 changes: 4 additions & 1 deletion base/strings/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ or a regular expression.
If `r` is a function, each occurrence is replaced with `r(s)`
where `s` is the matched substring (when `pat`is a `Regex` or `AbstractString`) or
character (when `pat` is an `AbstractChar` or a collection of `AbstractChar`).
If `pat` is a regular expression and `r` is a `SubstitutionString`, then capture group
If `pat` is a regular expression and `r` is a [`SubstitutionString`](@ref), then capture group
references in `r` are replaced with the corresponding matched text.
To remove instances of `pat` from `string`, set `r` to the empty `String` (`""`).

Expand All @@ -466,6 +466,9 @@ julia> replace("The quick foxes run quickly.", "quick" => "slow", count=1)

julia> replace("The quick foxes run quickly.", "quick" => "", count=1)
"The foxes run quickly."

julia> replace("The quick foxes run quickly.", r"fox(es)?" => s"bus\\1")
"The quick buses run quickly."
```
"""
replace(s::AbstractString, pat_f::Pair; count=typemax(Int)) =
Expand Down
2 changes: 2 additions & 0 deletions doc/src/base/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Base.codeunit
Base.codeunits
Base.ascii
Base.@r_str
Base.SubstitutionString
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK we only list exported objects here, yet SubstitutionString isn't exported. I guess it should be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seem to be a few exceptions to that (eg. BroadcastStyle in arrays.md, OneTo in math.md). I added SubstitutionString here only because Documenter needed that to be able to generate cross-reference from replace's doc. I'm not sure it makes sense to export SubstitutionString though: it's somewhat cumbersome to use as a constructor (with the longer name than s"" and the need for additional backslashes), and as a type it's useful (afaict) only to the very few people building RegEx libraries. Perhaps I should go with my original idea of only documenting @s_str and linking directly to that from replace's doc - that's probably more useful from a practical point of view too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex is exported even though the same objections apply, so I don't think that's a problem.

Base.@s_str
Base.@raw_str
Base.Docs.@html_str
Base.Docs.@text_str
Expand Down