Class StringFormat
return new StringFormat("{address}+{subaddress}@{domain}")
.parse("my-ldap+test@google.com", (address, subaddress, domain) -> ...);
An ErrorProne check is provided to guard against incorrect lambda parameters to the
parse()
, parseOrThrow()
, parseGreedy()
and scan()
methods. Both the
number of parameters and the lambda parameter names are checked to ensure they match the format
string. The arguments passed to the format
are also checked. If you use bazel, the check
is automatically enforced.
Starting from 6.7, if a certain placeholder is uninteresting and you'd rather not name it, you
can use the special ...
placeholder and then you won't need to assign a lambda variable
to capture it:
return new StringFormat("{...}+{subaddress}@{domain}")
.parse("my-ldap+test@google.com", (subaddress, domain) -> ...);
Note that except the placeholders, characters in the format string are treated as literals.
This works better if your pattern is close to free-form text with characters like '.', '?', '(',
'|' and whatnot because you don't need to escape them. On the other hand, the literal characters
won't offer regex functionalities you get from (\w+)
, (foo|bar)
etc.
In the face of ambiguity, the parse()
methods can be lossy. Consider the format string
of String.format("I bought %s and %s", "apples and oranges", "chips")
, it returns
"I bought apples and oranges and chips"
; but the following parsing code will incorrectly parse
"apples" as "{fruits}" and "oranges and chips" as "{snacks}":
new StringFormat("I bought {fruits} and {snacks}")
.parse("I bought apples and oranges and chips", (fruits, snacks) -> ...);
As such, only use this class on trusted input strings (i.e. not user inputs). And use regex
instead to better deal with ambiguity.
All the parse()
methods attempt to match the entire input string from beginning to
end. If you need to find the string format as a substring anywhere inside the input string, or
need to find repeated occurrences from the input string, use the scan()
methods instead.
Tack on .findFirst()
on the returned lazy stream if you only care to find a single
occurrence.
This class is immutable and pre-compiles the format string at constructor time so that the
parse()
and scan()
methods will be more efficient.
- Since:
- 6.6
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic interface
A functional SPI interface for custom interpolation.static interface
A template that will produce instances of typeT
, after filling the template placeholders with the given variadic parameters. -
Constructor Summary
ConstructorDescriptionStringFormat
(String format) Constructs a StringFormat with placeholders in the syntax of"{foo}"
. -
Method Summary
Modifier and TypeMethodDescriptionfinal String
Returns the string formatted with placeholders filled usingargs
.final boolean
Returns true if this format matchesinput
entirely.final Optional
<List<Substring.Match>> Parsesinput
against the pattern.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 3 placeholder values in this string format.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 4 placeholder values in this string format.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 5 placeholder values in this string format.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 6 placeholder values in this string format.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 7 placeholder values in this string format.final <R> Optional
<R> Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 8 placeholder values in this string format.final <R> Optional
<R> parse
(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Parsesinput
and appliesmapper
with the two placeholder values in this string format.final <R> Optional
<R> Parsesinput
and applies themapper
function with the single placeholder value in this string format.final <R> Optional
<R> parseGreedy
(String input, MapFrom3<? super String, ? extends R> mapper) Similar toparse(String, MapFrom3)
, parsesinput
and appliesmapper
with the 3 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.final <R> Optional
<R> parseGreedy
(String input, MapFrom4<? super String, ? extends R> mapper) Similar toparse(String, MapFrom4)
, parsesinput
and appliesmapper
with the 3 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.final <R> Optional
<R> parseGreedy
(String input, MapFrom5<? super String, ? extends R> mapper) Similar toparse(String, MapFrom5)
, parsesinput
and appliesmapper
with the 5 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.final <R> Optional
<R> parseGreedy
(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Similar toparse(String, BiFunction)
, parsesinput
and appliesmapper
with the two placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.final <R> Optional
<R> parseGreedy
(String input, Function<? super String, ? extends R> mapper) Similar toparse(String, Function)
, parsesinput
and appliesmapper
with the single placeholder value in this format string, but matches the placeholders backwards from the end to the beginning of the input string.final <R> R
parseOrThrow
(String input, MapFrom3<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 3 placeholder values in this format string.final <R> R
parseOrThrow
(String input, MapFrom4<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 4 placeholder values in this string format.final <R> R
parseOrThrow
(String input, MapFrom5<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 5 placeholder values in this string format.final <R> R
parseOrThrow
(String input, MapFrom6<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 6 placeholder values in this string format.final <R> R
parseOrThrow
(String input, MapFrom7<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 7 placeholder values in this string format.final <R> R
parseOrThrow
(String input, MapFrom8<? super String, R> mapper) Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 8 placeholder values in this string format.final <R> R
parseOrThrow
(String input, BiFunction<? super String, ? super String, R> mapper) Parsesinput
and appliesmapper
with the two placeholder values in this format string.final <R> R
parseOrThrow
(String input, Function<? super String, R> mapper) Parsesinput
and appliesmapper
with the single placeholder value in this format string.final String
replaceAllFrom
(String input, MapFrom3<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, MapFrom4<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, MapFrom5<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, MapFrom6<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, MapFrom7<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, MapFrom8<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, BiFunction<? super Substring.Match, ? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final String
replaceAllFrom
(String input, Function<? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.final Stream
<List<Substring.Match>> Scans theinput
string and extracts all matched placeholders in this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> scan
(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Scans theinput
string and extracts all matches of this string format.final <R> Stream
<R> Scans theinput
string and extracts all matches of this string format.final <R> R
scanAndCollectFrom
(String input, BiCollector<? super String, ? super String, R> collector) Scans theinput
string and collects all pairs of placeholders defined by this string format usingcollector
.final <R> R
scanAndCollectFrom
(String input, Collector<? super String, ?, R> collector) Scans theinput
string and collects all matches of this string format usingcollector
.static Substring.Pattern
Returns aSubstring.Pattern
spanning the substring matchingformat
.static <T> StringFormat.Template
<T> template
(String template, StringFormat.Interpolator<? extends T> interpolator) Returns a go/jep-430 style template ofT
produced by interpolating arguments into thetemplate
string, using the giveninterpolator
function.static <T> StringFormat.Template
<T> Returns a factory of typeT
usingformat
string as the template, whose curly-braced placeholders will be filled with the template arguments and then passed to thecreator
function to create theT
instances.toString()
Returns the string format.static String
Returns string with the "{placeholder}"s intemplate
filled byargs
, in order.
-
Constructor Details
-
StringFormat
Constructs a StringFormat with placeholders in the syntax of"{foo}"
. For example:new StringFormat("Dear {customer}, your confirmation number is {conf#}");
Nesting "{placeholder}" syntax inside literal curly braces is supported. For example, you could use a format like:
"{name: {name}, age: {age}}"
, and it will be able to parse record-like strings such as "{name: Joe, age: 25}".- Parameters:
format
- the template format with placeholders- Throws:
IllegalArgumentException
- ifformat
is invalid (e.g. a placeholder immediately followed by another placeholder)
-
-
Method Details
-
using
Returns string with the "{placeholder}"s intemplate
filled byargs
, in order.In the not-so-distant future when string interpolation is supported, you'll unlikely need String.format() or third-party templating. But you could still need to define some public template constants to be reused among multiple classes. For example:
throw new ApiException( StringFormat.with(StandardErrors.ACCOUNT_LOCKED, accountId, waitTime));
StringFormat.with("{foo}={bar}", foo, bar)
is equivalent tonew StringFormat("{foo}={bar}").format(foo, bar)
except that it's twice as fast and syntactically shorter when the format string is inlined as opposed to being stored as a constant StringFormat object.Compared to equivalent
String.format("%s=%s", foo, bar)
, using named placeholders works better if the template strings are public constants that are used across multiple classes. The compile-time placeholder name check helps to ensure that the arguments are passed correctly.Among the different formatting APIs, in the order of efficiency (fastest first):
FORMAT_CONSTANT.format(...)
.StringFormat.using(...)
andString.format(...)
in Java 21.new StringFormat("{foo}={bar}").format(...)
.String.format(...)
in Java 11
- Since:
- 8.0
-
span
Returns aSubstring.Pattern
spanning the substring matchingformat
. For example,StringFormat.span("projects/{project}/")
is equivalent tospanningInOrder("projects/", "/")
.Useful if you need a Substring.Pattern for purposes such as composition, but prefer a more self-documenting syntax. The placeholder names in the format string don't affect runtime semantics, but using meaningful names improves readability.
- Since:
- 7.0
-
to
public static <T> StringFormat.Template<T> to(Function<? super String, ? extends T> creator, String format) Returns a factory of typeT
usingformat
string as the template, whose curly-braced placeholders will be filled with the template arguments and then passed to thecreator
function to create theT
instances.A typical use case is to pre-create an exception template that can be used to create exceptions filled with different parameter values. For example:
private static final StringFormat.Template<IOException> JOB_FAILED = StringFormat.to( IOException::new, "Job ({job_id}) failed with {error_code}, details: {details}"); // 150 lines later. // Compile-time enforced that parameters are correct and in the right order. throw JOB_FAILED.with(jobId, errorCode, errorDetails);
- Since:
- 7.0
-
template
public static <T> StringFormat.Template<T> template(String template, StringFormat.Interpolator<? extends T> interpolator) Returns a go/jep-430 style template ofT
produced by interpolating arguments into thetemplate
string, using the giveninterpolator
function.The
interpolator
function is an SPI. That is, instead of users creating the lambda in-line, you are expected to provide a canned implementation -- typically by wrapping it inside a convenient facade class. For example:// Provided to the user: public final class BigQuery { public static Template<QueryRequest> template(String template) { return StringFormat.template(template, (fragments, placeholders) -> ...); } } // At call site: private static final Template<QueryRequest> GET_CASE_BY_ID = BigQuery.template( "SELECT CaseId, Description FROM tbl WHERE CaseId = '{case_id}'"); .... QueryRequest query = GET_CASE_BY_ID.with(caseId); // automatically escape special chars
This way, the StringFormat API provides compile-time safety, and the SPI plugs in custom interpolation logic.
Calling
StringFormat.Template.with(java.lang.Object...)
with unexpected number of parameters will throwIllegalArgumentException
without invokinginterpolator
.- Since:
- 7.0
-
parse
Parsesinput
and applies themapper
function with the single placeholder value in this string format.For example:
new StringFormat("Job failed (job id: {job_id})").parse(input, jobId -> ...);
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly one placeholder.
-
parse
public final <R> Optional<R> parse(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Parsesinput
and appliesmapper
with the two placeholder values in this string format.For example:
new StringFormat("Job failed (job id: '{id}', error code: {code})") .parse(input, (jobId, errorCode) -> ...);
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly two placeholders.
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 3 placeholder values in this string format.For example:
new StringFormat("Job failed (job id: '{job_id}', error code: {code}, error details: {details})") .parse(input, (jobId, errorCode, errorDetails) -> ...);
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 3 placeholders.
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 4 placeholder values in this string format.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 4 placeholders.
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 5 placeholder values in this string format.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 5 placeholders.
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 6 placeholder values in this string format.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 6 placeholders.
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 7 placeholder values in this string format.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 7 placeholders.- Since:
- 7.2
-
parse
Similar toparse(String, BiFunction)
, but parsesinput
and appliesmapper
with the 8 placeholder values in this string format.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if or the format string doesn't have exactly 8 placeholders.- Since:
- 7.2
-
parse
Parsesinput
against the pattern.Returns an immutable list of placeholder values in the same order as the placeholders in the format string, upon success; otherwise returns empty.
The
Substring.Match
result type allows caller to inspect the characters around each match, or to access the raw index in the input string. -
parseOrThrow
Parsesinput
and appliesmapper
with the single placeholder value in this format string.For example:
new StringFormat("Job failed (job id: {job_id})").parseOrThrow(input, jobId -> ...);
Unlike
parse(String, Function)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,java.util.function.Function<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly one placeholderNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Parsesinput
and appliesmapper
with the two placeholder values in this format string.For example:
new StringFormat("Job failed (job id: '{job_id}', error code: {error_code})") .parseOrThrow(input, (jobId, errorCode) -> ...);
Unlike
parse(String, BiFunction)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,java.util.function.BiFunction<? super java.lang.String,? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder value. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly two placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 3 placeholder values in this format string.For example:
new StringFormat("Job failed (id: '{job_id}', code: {error_code}, error details: {details})") .parseOrThrow(input, (jobId, errorCode, errorDetails) -> ...);
Unlike
parse(String, MapFrom3)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom3<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 3 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 4 placeholder values in this string format.Unlike
parse(String, MapFrom4)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom4<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 4 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 5 placeholder values in this string format.Unlike
parse(String, MapFrom5)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom5<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 5 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 6 placeholder values in this string format.Unlike
parse(String, MapFrom6)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom6<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 6 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.0
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 7 placeholder values in this string format.Unlike
parse(String, MapFrom6)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom6<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 7 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.2
-
parseOrThrow
Similar toparseOrThrow(String, BiFunction)
, but parsesinput
and appliesmapper
with the 8 placeholder values in this string format.Unlike
parse(String, MapFrom6)
,IllegalArgumentException
is thrown if the input string doesn't match the string format. The error message will include both the input string and the format string for ease of debugging, but is otherwise generic. If you need a different exception type, or need to customize the error message, consider usingAbstractStringFormat.<R>parse(java.lang.String,com.google.mu.function.MapFrom6<? super java.lang.String,? extends R>)
instead and callOptional.orElseThrow()
explicitly.- Returns:
- the return value of the
mapper
function applied on the extracted placeholder values. - Throws:
IllegalArgumentException
- if the input string doesn't match the string format, or if the format string doesn't have exactly 8 placeholdersNullPointerException
- if any of the parameter is null ormapper
returns null.- Since:
- 7.2
-
parseGreedy
Similar toparse(String, Function)
, parsesinput
and appliesmapper
with the single placeholder value in this format string, but matches the placeholders backwards from the end to the beginning of the input string.For unambiguous strings, it's equivalent to
parse(String, Function)
, but if for example you are parsing "a/b/c" against the pattern of "{parent}/{...}",parse("a/b/c", parent -> parent)
results in "a", whileparseGreedy("a/b/c", parent -> parent)
results in "a/b".This is also equivalent to allowing the left placeholder to match greedily, while still requiring the remaining placeholder(s) to be matched.
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the format string doesn't have exactly one placeholder.- Since:
- 7.0
-
parseGreedy
public final <R> Optional<R> parseGreedy(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Similar toparse(String, BiFunction)
, parsesinput
and appliesmapper
with the two placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.For unambiguous strings, it's equivalent to
parse(String, BiFunction)
, but if for example you are parsing "a/b/c" against the pattern of "{parent}/{child}",parse("a/b/c", (parent, child) -> ...)
parses out "a" as parent and "b/c" as child, whileparseGreedy("a/b/c", (parent, child) -> ...)
parses "a/b" as parent and "c" as child.This is also equivalent to allowing the left placeholder to match greedily, while still requiring the remaining placeholder(s) to be matched.
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the format string doesn't have exactly two placeholders.- Since:
- 7.0
-
parseGreedy
Similar toparse(String, MapFrom3)
, parsesinput
and appliesmapper
with the 3 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.This is also equivalent to allowing the left placeholder to match greedily, while still requiring the remaining placeholder(s) to be matched.
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the format string doesn't have exactly 3 placeholders.- Since:
- 7.0
-
parseGreedy
Similar toparse(String, MapFrom4)
, parsesinput
and appliesmapper
with the 3 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.This is also equivalent to allowing the left placeholder to match greedily, while still requiring the remaining placeholder(s) to be matched.
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the format string doesn't have exactly 4 placeholders.- Since:
- 7.0
-
parseGreedy
Similar toparse(String, MapFrom5)
, parsesinput
and appliesmapper
with the 5 placeholder values in this format string, but matches the placeholders backwards from the end to the beginning of the input string.This is also equivalent to allowing the left placeholder to match greedily, while still requiring the remaining placeholder(s) to be matched.
- Returns:
- the return value of the
mapper
function if not null. Returns empty ifinput
doesn't match the format, ormapper
returns null. - Throws:
IllegalArgumentException
- if the format string doesn't have exactly 5 placeholders.- Since:
- 7.0
-
matches
Returns true if this format matchesinput
entirely.- Since:
- 7.0
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.Note that while the placeholder value(s) are passed to the
replacement
function, the full matching substring of the string format (including but not limited to the placeholders) are replaced by the return value of thereplacement
function. So for example if you are trying to rewrite every"<{value}>"
to"<v...>"
, be sure to include the angle bracket characters as in:StringFormat bracketed = new StringFormat(""<{value}>""); String rewritten = bracketed.replaceAllFrom(input, value -> bracketed.format(value.charAt(0) + "..."));
If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter type.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 1 named placeholder- Since:
- 7.2
-
replaceAllFrom
public final String replaceAllFrom(String input, BiFunction<? super Substring.Match, ? super Substring.Match, ?> replacement) Scansinput
and replaces all matches using thereplacement
function.Note that while the placeholder value(s) are passed to the
replacement
function, the full matching substring of the string format (including but not limited to the placeholders) are replaced by the return value of thereplacement
function. So for example if you are trying to rewrite every"[{key}:{value}]"
to"[{key}={value}]"
, be sure to include the square bracket characters as in:StringFormat oldFormat = new StringFormat("[{key}:{value}]"); StringFormat newFormat = new StringFormat("[{key}={value}]"); String rewritten = oldFormat.replaceAllFrom(input, (key, value) -> newFormat.format(key, value));
If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 2 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 3 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 4 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 5 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 6 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 7 named placeholder- Since:
- 7.2
-
replaceAllFrom
Scansinput
and replaces all matches using thereplacement
function.If no match is found, the
input
string is returned.If
replacement
returns null, the match is ignored as if it didn't match the format. This can be used to post-filter the match with custom predicates (e.g. a placeholder value must be digits only).The
replacement
function acceptsSubstring.Match
instead of String to avoid unnecessary copying of the characters. If you are passing in a method reference, it can also take CharSequence or Object as the parameter types.- Throws:
IllegalArgumentException
- if the format string doesn't have exactly 8 named placeholder- Since:
- 7.2
-
scan
Scans theinput
string and extracts all matched placeholders in this string format.unlike
parse(String)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the single placeholder values to themapper
function for each iteration, with null results skipped.For example:
new StringFormat("/home/usr/myname/{file_name}\n") .scan(multiLineInput, fileName -> ...);
unlike
parse(String, Function)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If the placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
public final <R> Stream<R> scan(String input, BiFunction<? super String, ? super String, ? extends R> mapper) Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the two placeholder values to themapper
function for each iteration, with null results skipped.For example:
new StringFormat("[key={key}, value={value}]") .repeatedly() .parse(input, (key, value) -> ...);
unlike
parse(String, BiFunction)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 3 placeholder values to themapper
function for each iteration, with null results skipped.For example:
new StringFormat("[{lhs} + {rhs} = {result}]") .repeatedly() .parse(input, (lhs, rhs, result) -> ...);
unlike
parse(String, MapFrom3)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 4 placeholder values to themapper
function for each iteration, with null results skipped.unlike
parse(String, MapFrom4)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 5 placeholder values to themapper
function for each iteration, with null results skipped.unlike
parse(String, MapFrom5)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 6 placeholder values to themapper
function for each iteration, with null results skipped.unlike
parse(String, MapFrom6)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream. -
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 7 placeholder values to themapper
function for each iteration, with null results skipped.unlike
parse(String, MapFrom6)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream.- Since:
- 7.2
-
scan
Scans theinput
string and extracts all matches of this string format. Returns the lazy stream of non-null results from passing the 8 placeholder values to themapper
function for each iteration, with null results skipped.unlike
parse(String, MapFrom6)
, the input string isn't matched entirely: the pattern doesn't have to start from the beginning, and if there are some remaining characters that don't match the pattern any more, the stream stops. In particular, if there is no match, empty stream is returned.By default, placeholders are allowed to be matched against an empty string. If a certain placeholder isn't expected to be empty, consider filtering it out by returning null from the
mapper
function, which will then be ignored in the result stream.- Since:
- 7.2
-
scanAndCollectFrom
Scans theinput
string and collects all matches of this string format usingcollector
.For example:
List<String> fileNames = new StringFormat("/home/usr/myname/{file_name}\n") .scanAndCollectFrom(multiLineInput, toList());
- Throws:
IllegalArgumentException
- if the format string doesn't have exactly one placeholder.- Since:
- 8.0
-
scanAndCollectFrom
public final <R> R scanAndCollectFrom(String input, BiCollector<? super String, ? super String, R> collector) Scans theinput
string and collects all pairs of placeholders defined by this string format usingcollector
.For example:
Map<String, String> keyValues = new StringFormat("{{key}: {value}}") .scanAndCollectFrom(input, Collectors::toMap);
If you need to apply intermediary operations before collecting to the final result, consider using
BiStream::toBiStream
like the following code:ImmutableMap<UserId, EmailAddress> userEmails = new StringFormat("{{key}: {value}}") .scanAndCollectFrom(input, BiStream::toBiStream) .mapKeys(UserId::of) .mapValues(EmailAddress::parse) .toMap();
- Throws:
IllegalArgumentException
- if the format string doesn't have exactly two placeholders.- Since:
- 8.0
-
format
Returns the string formatted with placeholders filled usingargs
. This is the reverse operation of theparse(...)
methods. For example:new StringFormat("Hello {who}").format("world") => "Hello world"
- Throws:
IllegalArgumentException
- if the number of arguments doesn't match that of the placeholders
-
toString
Returns the string format.
-