1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.lang3; 18 19 import java.util.Objects; 20 import java.util.regex.Matcher; 21 import java.util.regex.Pattern; 22 23 /** 24 * Helpers to process Strings using regular expressions. 25 * 26 * @see java.util.regex.Pattern 27 * @since 3.8 28 */ 29 public class RegExUtils { 30 31 /** 32 * Compiles the given regular expression into a pattern with the {@link Pattern#DOTALL} flag. 33 * 34 * @param regex The expression to be compiled 35 * @return the given regular expression compiled into a pattern with the {@link Pattern#DOTALL} flag. 36 * @since 3.13.0 37 */ 38 public static Pattern dotAll(final String regex) { 39 return Pattern.compile(regex, Pattern.DOTALL); 40 } 41 42 /** 43 * Compiles the given regular expression into a pattern with the {@link Pattern#DOTALL} flag, then creates a matcher that will match the given text against 44 * this pattern. 45 * 46 * @param regex The expression to be compiled. 47 * @param text The character sequence to be matched. 48 * @return A new matcher for this pattern. 49 * @since 3.18.0 50 */ 51 public static Matcher dotAllMatcher(final String regex, final CharSequence text) { 52 return dotAll(regex).matcher(text); 53 } 54 55 /** 56 * Compiles the given regular expression into a pattern with the {@link Pattern#DOTALL} flag, then creates a matcher that will match the given text against 57 * this pattern. 58 * 59 * @param regex The expression to be compiled. 60 * @param text The character sequence to be matched. 61 * @return A new matcher for this pattern. 62 * @since 3.13.0 63 * @deprecated Use {@link #dotAllMatcher(String, CharSequence)}. 64 */ 65 @Deprecated 66 public static Matcher dotAllMatcher(final String regex, final String text) { 67 return dotAll(regex).matcher(text); 68 } 69 70 /** 71 * Removes each substring of the text String that matches the given regular expression pattern. 72 * 73 * This method is a {@code null} safe equivalent to: 74 * <ul> 75 * <li>{@code pattern.matcher(text).replaceAll(StringUtils.EMPTY)}</li> 76 * </ul> 77 * 78 * <p>A {@code null} reference passed to this method is a no-op.</p> 79 * 80 * <pre>{@code 81 * StringUtils.removeAll(null, *) = null 82 * StringUtils.removeAll("any", (Pattern) null) = "any" 83 * StringUtils.removeAll("any", Pattern.compile("")) = "any" 84 * StringUtils.removeAll("any", Pattern.compile(".*")) = "" 85 * StringUtils.removeAll("any", Pattern.compile(".+")) = "" 86 * StringUtils.removeAll("abc", Pattern.compile(".?")) = "" 87 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\nB" 88 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB" 89 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>", Pattern.DOTALL)) = "AB" 90 * StringUtils.removeAll("ABCabc123abc", Pattern.compile("[a-z]")) = "ABC123" 91 * }</pre> 92 * 93 * @param text text to remove from, may be null 94 * @param regex the regular expression to which this string is to be matched 95 * @return the text with any removes processed, 96 * {@code null} if null String input 97 * 98 * @see #replaceAll(CharSequence, Pattern, String) 99 * @see java.util.regex.Matcher#replaceAll(String) 100 * @see java.util.regex.Pattern 101 * @since 3.18.0 102 */ 103 public static String removeAll(final CharSequence text, final Pattern regex) { 104 return replaceAll(text, regex, StringUtils.EMPTY); 105 } 106 107 /** 108 * Removes each substring of the text String that matches the given regular expression pattern. 109 * 110 * This method is a {@code null} safe equivalent to: 111 * <ul> 112 * <li>{@code pattern.matcher(text).replaceAll(StringUtils.EMPTY)}</li> 113 * </ul> 114 * 115 * <p>A {@code null} reference passed to this method is a no-op.</p> 116 * 117 * <pre>{@code 118 * StringUtils.removeAll(null, *) = null 119 * StringUtils.removeAll("any", (Pattern) null) = "any" 120 * StringUtils.removeAll("any", Pattern.compile("")) = "any" 121 * StringUtils.removeAll("any", Pattern.compile(".*")) = "" 122 * StringUtils.removeAll("any", Pattern.compile(".+")) = "" 123 * StringUtils.removeAll("abc", Pattern.compile(".?")) = "" 124 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\nB" 125 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB" 126 * StringUtils.removeAll("A<__>\n<__>B", Pattern.compile("<.*>", Pattern.DOTALL)) = "AB" 127 * StringUtils.removeAll("ABCabc123abc", Pattern.compile("[a-z]")) = "ABC123" 128 * }</pre> 129 * 130 * @param text text to remove from, may be null 131 * @param regex the regular expression to which this string is to be matched 132 * @return the text with any removes processed, 133 * {@code null} if null String input 134 * 135 * @see #replaceAll(CharSequence, Pattern, String) 136 * @see java.util.regex.Matcher#replaceAll(String) 137 * @see java.util.regex.Pattern 138 * @deprecated Use {@link #removeAll(CharSequence, Pattern)}. 139 */ 140 @Deprecated 141 public static String removeAll(final String text, final Pattern regex) { 142 return replaceAll((CharSequence) text, regex, StringUtils.EMPTY); 143 } 144 145 /** 146 * Removes each substring of the text String that matches the given regular expression. 147 * 148 * This method is a {@code null} safe equivalent to: 149 * <ul> 150 * <li>{@code text.replaceAll(regex, StringUtils.EMPTY)}</li> 151 * <li>{@code Pattern.compile(regex).matcher(text).replaceAll(StringUtils.EMPTY)}</li> 152 * </ul> 153 * 154 * <p>A {@code null} reference passed to this method is a no-op.</p> 155 * 156 * <p>Unlike in the {@link #removePattern(CharSequence, String)} method, the {@link Pattern#DOTALL} option 157 * is NOT automatically added. 158 * To use the DOTALL option prepend {@code "(?s)"} to the regex. 159 * DOTALL is also known as single-line mode in Perl.</p> 160 * 161 * <pre>{@code 162 * StringUtils.removeAll(null, *) = null 163 * StringUtils.removeAll("any", (String) null) = "any" 164 * StringUtils.removeAll("any", "") = "any" 165 * StringUtils.removeAll("any", ".*") = "" 166 * StringUtils.removeAll("any", ".+") = "" 167 * StringUtils.removeAll("abc", ".?") = "" 168 * StringUtils.removeAll("A<__>\n<__>B", "<.*>") = "A\nB" 169 * StringUtils.removeAll("A<__>\n<__>B", "(?s)<.*>") = "AB" 170 * StringUtils.removeAll("ABCabc123abc", "[a-z]") = "ABC123" 171 * }</pre> 172 * 173 * @param text text to remove from, may be null 174 * @param regex the regular expression to which this string is to be matched 175 * @return the text with any removes processed, 176 * {@code null} if null String input 177 * 178 * @throws java.util.regex.PatternSyntaxException 179 * if the regular expression's syntax is invalid 180 * 181 * @see #replaceAll(String, String, String) 182 * @see #removePattern(CharSequence, String) 183 * @see String#replaceAll(String, String) 184 * @see java.util.regex.Pattern 185 * @see java.util.regex.Pattern#DOTALL 186 */ 187 public static String removeAll(final String text, final String regex) { 188 return replaceAll(text, regex, StringUtils.EMPTY); 189 } 190 191 /** 192 * Removes the first substring of the text string that matches the given regular expression pattern. 193 * 194 * This method is a {@code null} safe equivalent to: 195 * <ul> 196 * <li>{@code pattern.matcher(text).replaceFirst(StringUtils.EMPTY)}</li> 197 * </ul> 198 * 199 * <p>A {@code null} reference passed to this method is a no-op.</p> 200 * 201 * <pre>{@code 202 * StringUtils.removeFirst(null, *) = null 203 * StringUtils.removeFirst("any", (Pattern) null) = "any" 204 * StringUtils.removeFirst("any", Pattern.compile("")) = "any" 205 * StringUtils.removeFirst("any", Pattern.compile(".*")) = "" 206 * StringUtils.removeFirst("any", Pattern.compile(".+")) = "" 207 * StringUtils.removeFirst("abc", Pattern.compile(".?")) = "bc" 208 * StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\n<__>B" 209 * StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB" 210 * StringUtils.removeFirst("ABCabc123", Pattern.compile("[a-z]")) = "ABCbc123" 211 * StringUtils.removeFirst("ABCabc123abc", Pattern.compile("[a-z]+")) = "ABC123abc" 212 * }</pre> 213 * 214 * @param text text to remove from, may be null 215 * @param regex the regular expression pattern to which this string is to be matched 216 * @return the text with the first replacement processed, 217 * {@code null} if null String input 218 * 219 * @see #replaceFirst(String, Pattern, String) 220 * @see java.util.regex.Matcher#replaceFirst(String) 221 * @see java.util.regex.Pattern 222 * @since 3.18.0 223 */ 224 public static String removeFirst(final CharSequence text, final Pattern regex) { 225 return replaceFirst(text, regex, StringUtils.EMPTY); 226 } 227 228 /** 229 * Removes the first substring of the text string that matches the given regular expression pattern. 230 * 231 * This method is a {@code null} safe equivalent to: 232 * <ul> 233 * <li>{@code pattern.matcher(text).replaceFirst(StringUtils.EMPTY)}</li> 234 * </ul> 235 * 236 * <p>A {@code null} reference passed to this method is a no-op.</p> 237 * 238 * <pre>{@code 239 * StringUtils.removeFirst(null, *) = null 240 * StringUtils.removeFirst("any", (Pattern) null) = "any" 241 * StringUtils.removeFirst("any", Pattern.compile("")) = "any" 242 * StringUtils.removeFirst("any", Pattern.compile(".*")) = "" 243 * StringUtils.removeFirst("any", Pattern.compile(".+")) = "" 244 * StringUtils.removeFirst("abc", Pattern.compile(".?")) = "bc" 245 * StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("<.*>")) = "A\n<__>B" 246 * StringUtils.removeFirst("A<__>\n<__>B", Pattern.compile("(?s)<.*>")) = "AB" 247 * StringUtils.removeFirst("ABCabc123", Pattern.compile("[a-z]")) = "ABCbc123" 248 * StringUtils.removeFirst("ABCabc123abc", Pattern.compile("[a-z]+")) = "ABC123abc" 249 * }</pre> 250 * 251 * @param text text to remove from, may be null 252 * @param regex the regular expression pattern to which this string is to be matched 253 * @return the text with the first replacement processed, 254 * {@code null} if null String input 255 * 256 * @see #replaceFirst(String, Pattern, String) 257 * @see java.util.regex.Matcher#replaceFirst(String) 258 * @see java.util.regex.Pattern 259 * @deprecated Use {@link #removeFirst(CharSequence, Pattern)}. 260 */ 261 @Deprecated 262 public static String removeFirst(final String text, final Pattern regex) { 263 return replaceFirst(text, regex, StringUtils.EMPTY); 264 } 265 266 /** 267 * Removes the first substring of the text string that matches the given regular expression. 268 * 269 * This method is a {@code null} safe equivalent to: 270 * <ul> 271 * <li>{@code text.replaceFirst(regex, StringUtils.EMPTY)}</li> 272 * <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(StringUtils.EMPTY)}</li> 273 * </ul> 274 * 275 * <p>A {@code null} reference passed to this method is a no-op.</p> 276 * 277 * <p>The {@link Pattern#DOTALL} option is NOT automatically added. 278 * To use the DOTALL option prepend {@code "(?s)"} to the regex. 279 * DOTALL is also known as single-line mode in Perl.</p> 280 * 281 * <pre>{@code 282 * StringUtils.removeFirst(null, *) = null 283 * StringUtils.removeFirst("any", (String) null) = "any" 284 * StringUtils.removeFirst("any", "") = "any" 285 * StringUtils.removeFirst("any", ".*") = "" 286 * StringUtils.removeFirst("any", ".+") = "" 287 * StringUtils.removeFirst("abc", ".?") = "bc" 288 * StringUtils.removeFirst("A<__>\n<__>B", "<.*>") = "A\n<__>B" 289 * StringUtils.removeFirst("A<__>\n<__>B", "(?s)<.*>") = "AB" 290 * StringUtils.removeFirst("ABCabc123", "[a-z]") = "ABCbc123" 291 * StringUtils.removeFirst("ABCabc123abc", "[a-z]+") = "ABC123abc" 292 * }</pre> 293 * 294 * @param text text to remove from, may be null 295 * @param regex the regular expression to which this string is to be matched 296 * @return the text with the first replacement processed, 297 * {@code null} if null String input 298 * 299 * @throws java.util.regex.PatternSyntaxException 300 * if the regular expression's syntax is invalid 301 * 302 * @see #replaceFirst(String, String, String) 303 * @see String#replaceFirst(String, String) 304 * @see java.util.regex.Pattern 305 * @see java.util.regex.Pattern#DOTALL 306 */ 307 public static String removeFirst(final String text, final String regex) { 308 return replaceFirst(text, regex, StringUtils.EMPTY); 309 } 310 311 /** 312 * Removes each substring of the source String that matches the given regular expression using the DOTALL option. 313 * 314 * This call is a {@code null} safe equivalent to: 315 * <ul> 316 * <li>{@code text.replaceAll("(?s)" + regex, StringUtils.EMPTY)}</li> 317 * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(StringUtils.EMPTY)}</li> 318 * </ul> 319 * 320 * <p>A {@code null} reference passed to this method is a no-op.</p> 321 * 322 * <pre>{@code 323 * StringUtils.removePattern(null, *) = null 324 * StringUtils.removePattern("any", (String) null) = "any" 325 * StringUtils.removePattern("A<__>\n<__>B", "<.*>") = "AB" 326 * StringUtils.removePattern("ABCabc123", "[a-z]") = "ABC123" 327 * }</pre> 328 * 329 * @param text 330 * the source string 331 * @param regex 332 * the regular expression to which this string is to be matched 333 * @return The resulting {@link String} 334 * @see #replacePattern(CharSequence, String, String) 335 * @see String#replaceAll(String, String) 336 * @see Pattern#DOTALL 337 * @since 3.18.0 338 */ 339 public static String removePattern(final CharSequence text, final String regex) { 340 return replacePattern(text, regex, StringUtils.EMPTY); 341 } 342 343 /** 344 * Removes each substring of the source String that matches the given regular expression using the DOTALL option. 345 * 346 * This call is a {@code null} safe equivalent to: 347 * <ul> 348 * <li>{@code text.replaceAll("(?s)" + regex, StringUtils.EMPTY)}</li> 349 * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(StringUtils.EMPTY)}</li> 350 * </ul> 351 * 352 * <p>A {@code null} reference passed to this method is a no-op.</p> 353 * 354 * <pre>{@code 355 * StringUtils.removePattern(null, *) = null 356 * StringUtils.removePattern("any", (String) null) = "any" 357 * StringUtils.removePattern("A<__>\n<__>B", "<.*>") = "AB" 358 * StringUtils.removePattern("ABCabc123", "[a-z]") = "ABC123" 359 * }</pre> 360 * 361 * @param text 362 * the source string 363 * @param regex 364 * the regular expression to which this string is to be matched 365 * @return The resulting {@link String} 366 * @see #replacePattern(CharSequence, String, String) 367 * @see String#replaceAll(String, String) 368 * @see Pattern#DOTALL 369 * @deprecated use {@link #removePattern(CharSequence, String)}. 370 */ 371 @Deprecated 372 public static String removePattern(final String text, final String regex) { 373 return replacePattern((CharSequence) text, regex, StringUtils.EMPTY); 374 } 375 376 /** 377 * Replaces each substring of the text String that matches the given regular expression pattern with the given replacement. 378 * 379 * This method is a {@code null} safe equivalent to: 380 * <ul> 381 * <li>{@code pattern.matcher(text).replaceAll(replacement)}</li> 382 * </ul> 383 * 384 * <p>A {@code null} reference passed to this method is a no-op.</p> 385 * 386 * <pre>{@code 387 * StringUtils.replaceAll(null, *, *) = null 388 * StringUtils.replaceAll("any", (Pattern) null, *) = "any" 389 * StringUtils.replaceAll("any", *, null) = "any" 390 * StringUtils.replaceAll("", Pattern.compile(""), "zzz") = "zzz" 391 * StringUtils.replaceAll("", Pattern.compile(".*"), "zzz") = "zzz" 392 * StringUtils.replaceAll("", Pattern.compile(".+"), "zzz") = "" 393 * StringUtils.replaceAll("abc", Pattern.compile(""), "ZZ") = "ZZaZZbZZcZZ" 394 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("<.*>"), "z") = "z\nz" 395 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("<.*>", Pattern.DOTALL), "z") = "z" 396 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("(?s)<.*>"), "z") = "z" 397 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[a-z]"), "_") = "ABC___123" 398 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "_") = "ABC_123" 399 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "") = "ABC123" 400 * StringUtils.replaceAll("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2") = "Lorem_ipsum_dolor_sit" 401 * }</pre> 402 * 403 * @param text text to search and replace in, may be null 404 * @param regex the regular expression pattern to which this string is to be matched 405 * @param replacement the string to be substituted for each match 406 * @return the text with any replacements processed, 407 * {@code null} if null String input 408 * 409 * @see java.util.regex.Matcher#replaceAll(String) 410 * @see java.util.regex.Pattern 411 */ 412 public static String replaceAll(final CharSequence text, final Pattern regex, final String replacement) { 413 if (ObjectUtils.anyNull(text, regex, replacement)) { 414 return toStringOrNull(text); 415 } 416 return regex.matcher(text).replaceAll(replacement); 417 } 418 419 /** 420 * Replaces each substring of the text String that matches the given regular expression pattern with the given replacement. 421 * 422 * This method is a {@code null} safe equivalent to: 423 * <ul> 424 * <li>{@code pattern.matcher(text).replaceAll(replacement)}</li> 425 * </ul> 426 * 427 * <p>A {@code null} reference passed to this method is a no-op.</p> 428 * 429 * <pre>{@code 430 * StringUtils.replaceAll(null, *, *) = null 431 * StringUtils.replaceAll("any", (Pattern) null, *) = "any" 432 * StringUtils.replaceAll("any", *, null) = "any" 433 * StringUtils.replaceAll("", Pattern.compile(""), "zzz") = "zzz" 434 * StringUtils.replaceAll("", Pattern.compile(".*"), "zzz") = "zzz" 435 * StringUtils.replaceAll("", Pattern.compile(".+"), "zzz") = "" 436 * StringUtils.replaceAll("abc", Pattern.compile(""), "ZZ") = "ZZaZZbZZcZZ" 437 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("<.*>"), "z") = "z\nz" 438 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("<.*>", Pattern.DOTALL), "z") = "z" 439 * StringUtils.replaceAll("<__>\n<__>", Pattern.compile("(?s)<.*>"), "z") = "z" 440 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[a-z]"), "_") = "ABC___123" 441 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "_") = "ABC_123" 442 * StringUtils.replaceAll("ABCabc123", Pattern.compile("[^A-Z0-9]+"), "") = "ABC123" 443 * StringUtils.replaceAll("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2") = "Lorem_ipsum_dolor_sit" 444 * }</pre> 445 * 446 * @param text text to search and replace in, may be null 447 * @param regex the regular expression pattern to which this string is to be matched 448 * @param replacement the string to be substituted for each match 449 * @return the text with any replacements processed, 450 * {@code null} if null String input 451 * 452 * @see java.util.regex.Matcher#replaceAll(String) 453 * @see java.util.regex.Pattern 454 * @deprecated Use {@link #replaceAll(CharSequence, Pattern, String)}. 455 */ 456 @Deprecated 457 public static String replaceAll(final String text, final Pattern regex, final String replacement) { 458 return replaceAll((CharSequence) text, regex, replacement); 459 } 460 461 /** 462 * Replaces each substring of the text String that matches the given regular expression 463 * with the given replacement. 464 * 465 * This method is a {@code null} safe equivalent to: 466 * <ul> 467 * <li>{@code text.replaceAll(regex, replacement)}</li> 468 * <li>{@code Pattern.compile(regex).matcher(text).replaceAll(replacement)}</li> 469 * </ul> 470 * 471 * <p>A {@code null} reference passed to this method is a no-op.</p> 472 * 473 * <p>Unlike in the {@link #replacePattern(CharSequence, String, String)} method, the {@link Pattern#DOTALL} option 474 * is NOT automatically added. 475 * To use the DOTALL option prepend {@code "(?s)"} to the regex. 476 * DOTALL is also known as single-line mode in Perl.</p> 477 * 478 * <pre>{@code 479 * StringUtils.replaceAll(null, *, *) = null 480 * StringUtils.replaceAll("any", (String) null, *) = "any" 481 * StringUtils.replaceAll("any", *, null) = "any" 482 * StringUtils.replaceAll("", "", "zzz") = "zzz" 483 * StringUtils.replaceAll("", ".*", "zzz") = "zzz" 484 * StringUtils.replaceAll("", ".+", "zzz") = "" 485 * StringUtils.replaceAll("abc", "", "ZZ") = "ZZaZZbZZcZZ" 486 * StringUtils.replaceAll("<__>\n<__>", "<.*>", "z") = "z\nz" 487 * StringUtils.replaceAll("<__>\n<__>", "(?s)<.*>", "z") = "z" 488 * StringUtils.replaceAll("ABCabc123", "[a-z]", "_") = "ABC___123" 489 * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "_") = "ABC_123" 490 * StringUtils.replaceAll("ABCabc123", "[^A-Z0-9]+", "") = "ABC123" 491 * StringUtils.replaceAll("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2") = "Lorem_ipsum_dolor_sit" 492 * }</pre> 493 * 494 * @param text text to search and replace in, may be null 495 * @param regex the regular expression to which this string is to be matched 496 * @param replacement the string to be substituted for each match 497 * @return the text with any replacements processed, 498 * {@code null} if null String input 499 * 500 * @throws java.util.regex.PatternSyntaxException 501 * if the regular expression's syntax is invalid 502 * 503 * @see #replacePattern(String, String, String) 504 * @see String#replaceAll(String, String) 505 * @see java.util.regex.Pattern 506 * @see java.util.regex.Pattern#DOTALL 507 */ 508 public static String replaceAll(final String text, final String regex, final String replacement) { 509 if (ObjectUtils.anyNull(text, regex, replacement)) { 510 return text; 511 } 512 return text.replaceAll(regex, replacement); 513 } 514 515 /** 516 * Replaces the first substring of the text string that matches the given regular expression pattern 517 * with the given replacement. 518 * 519 * This method is a {@code null} safe equivalent to: 520 * <ul> 521 * <li>{@code pattern.matcher(text).replaceFirst(replacement)}</li> 522 * </ul> 523 * 524 * <p>A {@code null} reference passed to this method is a no-op.</p> 525 * 526 * <pre>{@code 527 * StringUtils.replaceFirst(null, *, *) = null 528 * StringUtils.replaceFirst("any", (Pattern) null, *) = "any" 529 * StringUtils.replaceFirst("any", *, null) = "any" 530 * StringUtils.replaceFirst("", Pattern.compile(""), "zzz") = "zzz" 531 * StringUtils.replaceFirst("", Pattern.compile(".*"), "zzz") = "zzz" 532 * StringUtils.replaceFirst("", Pattern.compile(".+"), "zzz") = "" 533 * StringUtils.replaceFirst("abc", Pattern.compile(""), "ZZ") = "ZZabc" 534 * StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("<.*>"), "z") = "z\n<__>" 535 * StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("(?s)<.*>"), "z") = "z" 536 * StringUtils.replaceFirst("ABCabc123", Pattern.compile("[a-z]"), "_") = "ABC_bc123" 537 * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_") = "ABC_123abc" 538 * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "") = "ABC123abc" 539 * StringUtils.replaceFirst("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2") = "Lorem_ipsum dolor sit" 540 * }</pre> 541 * 542 * @param text text to search and replace in, may be null 543 * @param regex the regular expression pattern to which this string is to be matched 544 * @param replacement the string to be substituted for the first match 545 * @return the text with the first replacement processed, 546 * {@code null} if null String input 547 * 548 * @see java.util.regex.Matcher#replaceFirst(String) 549 * @see java.util.regex.Pattern 550 * @since 3.18.0 551 */ 552 public static String replaceFirst(final CharSequence text, final Pattern regex, final String replacement) { 553 if (text == null || regex == null || replacement == null) { 554 return toStringOrNull(text); 555 } 556 return regex.matcher(text).replaceFirst(replacement); 557 } 558 559 /** 560 * Replaces the first substring of the text string that matches the given regular expression pattern 561 * with the given replacement. 562 * 563 * This method is a {@code null} safe equivalent to: 564 * <ul> 565 * <li>{@code pattern.matcher(text).replaceFirst(replacement)}</li> 566 * </ul> 567 * 568 * <p>A {@code null} reference passed to this method is a no-op.</p> 569 * 570 * <pre>{@code 571 * StringUtils.replaceFirst(null, *, *) = null 572 * StringUtils.replaceFirst("any", (Pattern) null, *) = "any" 573 * StringUtils.replaceFirst("any", *, null) = "any" 574 * StringUtils.replaceFirst("", Pattern.compile(""), "zzz") = "zzz" 575 * StringUtils.replaceFirst("", Pattern.compile(".*"), "zzz") = "zzz" 576 * StringUtils.replaceFirst("", Pattern.compile(".+"), "zzz") = "" 577 * StringUtils.replaceFirst("abc", Pattern.compile(""), "ZZ") = "ZZabc" 578 * StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("<.*>"), "z") = "z\n<__>" 579 * StringUtils.replaceFirst("<__>\n<__>", Pattern.compile("(?s)<.*>"), "z") = "z" 580 * StringUtils.replaceFirst("ABCabc123", Pattern.compile("[a-z]"), "_") = "ABC_bc123" 581 * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "_") = "ABC_123abc" 582 * StringUtils.replaceFirst("ABCabc123abc", Pattern.compile("[^A-Z0-9]+"), "") = "ABC123abc" 583 * StringUtils.replaceFirst("Lorem ipsum dolor sit", Pattern.compile("( +)([a-z]+)"), "_$2") = "Lorem_ipsum dolor sit" 584 * }</pre> 585 * 586 * @param text text to search and replace in, may be null 587 * @param regex the regular expression pattern to which this string is to be matched 588 * @param replacement the string to be substituted for the first match 589 * @return the text with the first replacement processed, 590 * {@code null} if null String input 591 * 592 * @see java.util.regex.Matcher#replaceFirst(String) 593 * @see java.util.regex.Pattern 594 * @deprecated Use {@link #replaceFirst(CharSequence, Pattern, String)}. 595 */ 596 @Deprecated 597 public static String replaceFirst(final String text, final Pattern regex, final String replacement) { 598 return replaceFirst((CharSequence) text, regex, replacement); 599 } 600 601 /** 602 * Replaces the first substring of the text string that matches the given regular expression 603 * with the given replacement. 604 * 605 * This method is a {@code null} safe equivalent to: 606 * <ul> 607 * <li>{@code text.replaceFirst(regex, replacement)}</li> 608 * <li>{@code Pattern.compile(regex).matcher(text).replaceFirst(replacement)}</li> 609 * </ul> 610 * 611 * <p>A {@code null} reference passed to this method is a no-op.</p> 612 * 613 * <p>The {@link Pattern#DOTALL} option is NOT automatically added. 614 * To use the DOTALL option prepend {@code "(?s)"} to the regex. 615 * DOTALL is also known as single-line mode in Perl.</p> 616 * 617 * <pre>{@code 618 * StringUtils.replaceFirst(null, *, *) = null 619 * StringUtils.replaceFirst("any", (String) null, *) = "any" 620 * StringUtils.replaceFirst("any", *, null) = "any" 621 * StringUtils.replaceFirst("", "", "zzz") = "zzz" 622 * StringUtils.replaceFirst("", ".*", "zzz") = "zzz" 623 * StringUtils.replaceFirst("", ".+", "zzz") = "" 624 * StringUtils.replaceFirst("abc", "", "ZZ") = "ZZabc" 625 * StringUtils.replaceFirst("<__>\n<__>", "<.*>", "z") = "z\n<__>" 626 * StringUtils.replaceFirst("<__>\n<__>", "(?s)<.*>", "z") = "z" 627 * StringUtils.replaceFirst("ABCabc123", "[a-z]", "_") = "ABC_bc123" 628 * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "_") = "ABC_123abc" 629 * StringUtils.replaceFirst("ABCabc123abc", "[^A-Z0-9]+", "") = "ABC123abc" 630 * StringUtils.replaceFirst("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2") = "Lorem_ipsum dolor sit" 631 * }</pre> 632 * 633 * @param text text to search and replace in, may be null 634 * @param regex the regular expression to which this string is to be matched 635 * @param replacement the string to be substituted for the first match 636 * @return the text with the first replacement processed, 637 * {@code null} if null String input 638 * 639 * @throws java.util.regex.PatternSyntaxException 640 * if the regular expression's syntax is invalid 641 * 642 * @see String#replaceFirst(String, String) 643 * @see java.util.regex.Pattern 644 * @see java.util.regex.Pattern#DOTALL 645 */ 646 public static String replaceFirst(final String text, final String regex, final String replacement) { 647 if (text == null || regex == null || replacement == null) { 648 return text; 649 } 650 return text.replaceFirst(regex, replacement); 651 } 652 653 /** 654 * Replaces each substring of the source String that matches the given regular expression with the given 655 * replacement using the {@link Pattern#DOTALL} option. DOTALL is also known as single-line mode in Perl. 656 * 657 * This call is a {@code null} safe equivalent to: 658 * <ul> 659 * <li>{@code text.replaceAll("(?s)" + regex, replacement)}</li> 660 * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(replacement)}</li> 661 * </ul> 662 * 663 * <p>A {@code null} reference passed to this method is a no-op.</p> 664 * 665 * <pre>{@code 666 * StringUtils.replacePattern(null, *, *) = null 667 * StringUtils.replacePattern("any", (String) null, *) = "any" 668 * StringUtils.replacePattern("any", *, null) = "any" 669 * StringUtils.replacePattern("", "", "zzz") = "zzz" 670 * StringUtils.replacePattern("", ".*", "zzz") = "zzz" 671 * StringUtils.replacePattern("", ".+", "zzz") = "" 672 * StringUtils.replacePattern("<__>\n<__>", "<.*>", "z") = "z" 673 * StringUtils.replacePattern("ABCabc123", "[a-z]", "_") = "ABC___123" 674 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_") = "ABC_123" 675 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "") = "ABC123" 676 * StringUtils.replacePattern("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2") = "Lorem_ipsum_dolor_sit" 677 * }</pre> 678 * 679 * @param text 680 * the source string 681 * @param regex 682 * the regular expression to which this string is to be matched 683 * @param replacement 684 * the string to be substituted for each match 685 * @return The resulting {@link String} 686 * @see #replaceAll(String, String, String) 687 * @see String#replaceAll(String, String) 688 * @see Pattern#DOTALL 689 * @since 3.18.0 690 */ 691 public static String replacePattern(final CharSequence text, final String regex, final String replacement) { 692 if (ObjectUtils.anyNull(text, regex, replacement)) { 693 return toStringOrNull(text); 694 } 695 return dotAllMatcher(regex, text).replaceAll(replacement); 696 } 697 698 /** 699 * Replaces each substring of the source String that matches the given regular expression with the given 700 * replacement using the {@link Pattern#DOTALL} option. DOTALL is also known as single-line mode in Perl. 701 * 702 * This call is a {@code null} safe equivalent to: 703 * <ul> 704 * <li>{@code text.replaceAll("(?s)" + regex, replacement)}</li> 705 * <li>{@code Pattern.compile(regex, Pattern.DOTALL).matcher(text).replaceAll(replacement)}</li> 706 * </ul> 707 * 708 * <p>A {@code null} reference passed to this method is a no-op.</p> 709 * 710 * <pre>{@code 711 * StringUtils.replacePattern(null, *, *) = null 712 * StringUtils.replacePattern("any", (String) null, *) = "any" 713 * StringUtils.replacePattern("any", *, null) = "any" 714 * StringUtils.replacePattern("", "", "zzz") = "zzz" 715 * StringUtils.replacePattern("", ".*", "zzz") = "zzz" 716 * StringUtils.replacePattern("", ".+", "zzz") = "" 717 * StringUtils.replacePattern("<__>\n<__>", "<.*>", "z") = "z" 718 * StringUtils.replacePattern("ABCabc123", "[a-z]", "_") = "ABC___123" 719 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "_") = "ABC_123" 720 * StringUtils.replacePattern("ABCabc123", "[^A-Z0-9]+", "") = "ABC123" 721 * StringUtils.replacePattern("Lorem ipsum dolor sit", "( +)([a-z]+)", "_$2") = "Lorem_ipsum_dolor_sit" 722 * }</pre> 723 * 724 * @param text 725 * the source string 726 * @param regex 727 * the regular expression to which this string is to be matched 728 * @param replacement 729 * the string to be substituted for each match 730 * @return The resulting {@link String} 731 * @see #replaceAll(String, String, String) 732 * @see String#replaceAll(String, String) 733 * @see Pattern#DOTALL 734 * @deprecated Use {@link #replacePattern(CharSequence, String, String)}. 735 */ 736 @Deprecated 737 public static String replacePattern(final String text, final String regex, final String replacement) { 738 return replacePattern((CharSequence) text, regex, replacement); 739 } 740 741 private static String toStringOrNull(final CharSequence text) { 742 return Objects.toString(text, null); 743 } 744 745 /** 746 * Make private in 4.0. 747 * 748 * @deprecated TODO Make private in 4.0. 749 */ 750 @Deprecated 751 public RegExUtils() { 752 // empty 753 } 754 }