首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 正則表達式實戰:replaceAll 與後向引用解決字符串星號處理難題

     編輯:Java 綜合教學

Java 正則表達式實戰:replaceAll 與後向引用解決字符串星號處理難題

問題描述

面試真題:給定字符串,刪除中間的 *,保留首尾的 *。
示例:*ab**de** → *abde*

方案一:捕獲組 + 後向引用(標準解法)

str.replaceAll("(^\\*)|(\\*$)|\\*", "$1$2");

正則解析

  • (^\\*):捕獲組 1,匹配行首 *
  • (\\*$):捕獲組 2,匹配行尾 *
  • \\*:匹配任意位置的 *
  • |:或關係,優先匹配首尾

替換邏輯

  • $1$2:引用捕獲組 1 和 2 的內容
  • 首尾 * 被捕獲組匹配 → 替換為自身(保留)
  • 中間 * 被第三部分匹配 → 替換為空字符串(刪除)

關鍵細節

  1. Java 字符串中 \\ 代表正則的 \,故 * 需寫作 \\*
  2. 正則中後向引用用 \1,但 replaceAll 替換字符串中必須用 $1(Perl 風格)

方案二:零寬斷言(負向環視)

str.replaceAll("(?
  • (?:負向後顧斷言,當前位置不是行首
  • (?!$):負向前顧斷言,當前位置不是行尾
  • 僅匹配非首尾的 *,直接替換為空

效率最高,無捕獲組開銷。

方案三:貪婪 vs 惰性匹配陷阱

// 有缺陷:尾部連續 * 會被貪婪匹配全部吃掉
str.replaceAll("(^\\*)|(\\*$)|\\*+", "$1$2");

// 修正:改為惰性匹配
str.replaceAll("(^\\*)|(\\*$)|\\*+?", "$1$2");

貪婪模式 \*+ 會匹配盡可能多的 *,導致尾部多個 * 被誤刪;加 ? 切換為惰性模式即可修復。

性能對比與工具推薦

使用 Regex101 可視化調試、查看匹配步數。實測方案二(零寬斷言)步數最少,效率最高。

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved