java - Android/Java 正则表达式从子字符串中删除多余的零

标签 java android regex string

我有以下字符串作为输入:

"2.0,3.00,-4.0,0.00,-0.00,0.03,2.01,0.001,-0.03,101"

最终输出如下:

"2,3,-4,0,0,.03,2.01,.001,-.03,101"

所有前导零和尾随零都将被删除,正/负零都将简单地为零。

我们可以通过首先拆分字符串并对每个部分使用正则表达式来实现这一点。但是我的字符串大小超过 10000
我们如何使用 Regex 实现这一点?

编辑:

答案分析:

我已经用 String "0.00,-0.00,00.00,-00.00,40.00,-40.00,4.0,-4.0,4.01,-4.01,04.01,-04.01,004.04,-004.04,0004.040 测试了所有答案,-0004.040,101,.40,-.40,0.40,-0.40"Wiktor Stribiżew 的回答通过了所有测试用例。(参见此处: https://regex101.com/r/tS8hE3/9 ) 其他答案在大多数情况下都通过了,但不是全部。

最佳答案

更新的测试用例答案

使用以下正则表达式:

String rx = "-?0+\\.(0)+\\b|\\.0+\\b|\\b0+(?=\\.\\d*[1-9])|\\b0+(?=[1-9]\\d*\\.)|(\\.\\d*?)0+\\b";

并替换为 $1$2。参见 another demo .

正则表达式匹配多个备选方案并捕获字符串的某些部分以便稍后在替换期间重新插入:

  • -?0+\.(0)+\b - 匹配可选的 - 后跟一个或多个 0 后跟一个 . 然后 捕获 正好是一个 0 但匹配一次或多次出现(因为 (...)放在 0 上,+ 应用于该组);最后的单词边界要求在最后匹配的 0 之后出现一个非单词字符。在替换中,我们使用 $1 反向引用恢复 0。因此,-00.0000.00 将替换为 0
  • | - 或者...
  • \.0+\b - 在 , 之前一个点后跟一个或多个零(因为字符串是逗号分隔的)。
  • | - 或者...
  • \b0+(?=\.\d*[1-9]) - 单词边界(字符串的开头或 , 之后的位置)后跟一个或多个 0 后跟 . + 零个或多个数字后跟一个非 0 数字(因此我们删除仅由零组成的整数部分中的前导零)
  • | - 或者...
  • \b0+(?=[1-9]\d*\.) - 单词边界后跟一个或多个零,然后是 之前的非 0 数字。(因此,我们从不等于 0 的整数部分中删除所有前导零)。
  • | - 或者...
  • (\.\d*?)0+\b - 捕获 .+ 零个或多个数字,但尽可能少,直到第一个 0,然后只匹配一个或多个零(直到字符串或 , 的末尾)(因此,我们去掉了小数部分的尾随零)

测试用例更新前的回答

我建议使用一个非常简单和简短的正则表达式来满足您的需要:

-0+\.(0)+\b|\.0+\b|\b0+(?=\.\d*[1-9])

替换为$1

参见 regex demo .短IDEONE demo :

String re = "-0+\\.(0)+\\b|\\.0+\\b|\\b0+(?=\\.\\d*[1-9])"; 
String str = "2.0,3.00,-4.0,0.00,-0.00,0.03,2.01,0.001,-0.03,101,0.001,-0.03";
String expected = "2,3,-4,0,0,.03,2.01,.001,-.03,101,.001,-.03"; 
System.out.println(str.replaceAll(re, "$1").equals(expected)); // TRUE

解释:

  • -0+\.(0)+\b - 减号后跟一个或多个 0 (0+)带有文字点 (\.) 后跟一个或多个零(并仅捕获与 (0)+ 匹配的最后一个 0)带有单词边界(在此上下文中位于 , 之前)
  • | - 或者...
  • \.0+\b - 一个文字点 (\.) 后跟一个或多个零,然后是单词边界(位置在 之前, 在这种情况下)
  • | - 或者...
  • \b0+(?=\.\d*[1-9]) - 单词边界(在此上下文中位于 , 之后)后跟一个或多个零,后面必须跟一个文字点 (\.),然后是零个或多个数字,然后是 1 到 9 范围内的数字(以便小数部分更比 0)。

关于java - Android/Java 正则表达式从子字符串中删除多余的零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34985710/

相关文章:

java - 如何在不使用 !important 的情况下覆盖 GWT 中的默认样式

java - Android:使用 128 位 key 大小和 128 位 block 大小解密 AES - block 密码模式:CBC-CS1

android - 默认情况下,Android 手机上的 Firebase FCM token 存储在哪里

python - 将 HTML 列表 (<li>) 转换为制表符(即缩进)

java - 如何自动加载 servlet-context.xml?

java - ActiveMQ + MQTT + 订阅 "ActiveMQ.Advisory.Connection"

java - 检索 domain.tld 的正则表达式

Android按钮文字外观

java - 用 Java 中的正则表达式替换

regex - .htaccess:对子文件夹的内部重写,拒绝通过子文件夹的访问