【问题标题】:Regex for negative number with leading zeros and words with apastrophe带有前导零的负数和带有撇号的单词的正则表达式
【发布时间】:2022-01-10 01:11:25
【问题描述】:

嘿,我需要一个删除前导零的正则表达式。 现在我正在使用这段代码。它确实有效,只是不保留负号。

String regex = "^+(?!$)";
String numbers = txaTexte.getText().replaceAll(regex, ")

然后我拆分数字,以便将数字放入一个数组中。

input :
-0005
0003
-87

output :
-5
3
-87

我也想知道我可以使用什么正则表达式来获得这个。 箭头之前的词是输入,之后是输出 文本是法文的。现在我正在使用它,但它不能与撇号一起使用。

String [] tab = txaTexte.getText().split("(?:(?<![a-zA-Z])'|'(?![a-zA-Z])|[^a-zA-Z'])+")

美丽的 JOUR。 —> Un/beau/JOUR

La boîte crânienne —> La/boîte/crânienne

C'était mieux aujourd'hui —> C'/était/mieux/aujourd'hui

qu'autrefois —> qu'/autrefois

D'hier jusqu'à demain! —> D'/hier/jusqu'/à/demain

Dans mon sous-sol—> Dans/mon/sous-sol

【问题讨论】:

  • -0000 的结果应该是什么?一个错误? -0?只是0?
  • 应该是 0

标签: java regex


【解决方案1】:

您可以捕获一个可选的连字符,然后再匹配 1 次以上的零,并且 1 捕获第 2 组中从数字 1-9 开始的 1 个或多个数字

^(-?)0+([1-9]\d*)$
  • ^ 字符串开始
  • (-?) 捕获组 1,匹配可选连字符
  • 0+ 匹配 0+ 个零
  • ([1-9]\d*)捕获组2,匹配1-9开头的1+位
  • $字符串结束

查看regex demo。

在替换使用组 1 和组 2。

String regex = "^(-?)0+([1-9]\\d*)$";
String text = "-0005";
String numbers = txaTexte.getText().replaceAll(regex, "$1$2");

【讨论】:

【解决方案2】:

这是一种方法。这样可以保留标志。

  • 捕获可选符号。
  • 检查 0 个或多个前导零
  • 后跟一位或多位数字。
String regex = "^([+-])?0*(\\d+)";
String [] data = {"-1415", "+2924", "-0000123", "000322", "+000023"};
for (String num : data) {
    String after = num.replaceAll(regex, "$1$2");
    System.out.printf("%8s --> %s%n", num , after);
}

打印

   -1415 --> -1415
   +2924 --> +2924
-0000123 --> -123
  000322 --> 322
 +000023 --> +23

【讨论】:

    【解决方案3】:

    如果您想将-000、000、+0000 等保留为0,试试这个正则表达式:

    `^[-+]?0*(0)$|^([-+])?0*(\d+)$`
    

    分解:

    • ^...$ 表示整个字符串应该匹配(^ 是字符串的开头,$ 是结尾)
    • ...|... 是另一种选择
    • [-+] 是一个只包含加号和减号字符的字符类。请注意,如果- 不是第一个或最后一个字符,则它在字符类中具有特殊含义(“范围”)
    • (...) 是一个捕获组,可以在替换字符串中由$number 引用,其中number 是该组在正则表达式中的从 1 开始的 1 位位置(第一个开始的组是 1 等.)
    • ?、* 和 + 是在字符类之外使用时的量词,表示“0 或 1 次出现”(?)、“任意数量的出现,包括没有出现”(*) 和“至少一个发生”(+)
    • ^[-+]?0*(0)$ 因此意味着:整个字符串必须是可选符号,后跟任意数量的零并以单个零结尾,该零被捕获为组 1。
    • 或者^([-+])?0*(\d+)$ 表示整个字符串必须是一个可选符号,作为第 2 组捕获,后跟任意数量的零并以至少一位作为第 3 组捕获。

    然后可以将此正则表达式与 String.replaceAll(regex, "$1$2$3") 一起使用,以便仅保留第 1 组中的单个 0 或可选符号和第 2 组和第 3 组中不带前导零的数字。任何空组都将产生空字符串,这就是它起作用的原因。

    但是,正则表达式可能会很慢,尤其是当您必须处理大量字符串时。

    改进这一点的方法是只编译一次模式:

    //compile the pattern once and reuse it
    Pattern p = Pattern.compile("^[+-]?0*(0)$|^([+-])?0*(\\d+)$");
    
    //build a matcher from the pattern and the input string, and do the replacement
    String number = p.matcher(txaTexte.getText()).replaceAll("$1$2$3");
    

    如果您正在处理大量字符串 (> 10000),您可能希望使用一些没有正则表达式的专门的普通解析。考虑这样的事情,在我的机器上比使用重用模式的正则表达式方法快大约 10 倍:

    public static String stripLeadingZeros(String s) {
        //nothing to do, return the string as is
        if( s == null || s.isEmpty() ) {
            return s;
        }
        
        char[] chars = s.toCharArray();     
        int usedChars = 0;
        
        //check if the first character is the sign
        boolean hasSign = false;
        if(chars[0] == '-' || chars[0] == '+') {
          hasSign = true;
          usedChars++;
          
          //special case: just a sign
          if(chars.length == 1) {
              return s;
          }
        }
        
        //process the rest of the characters
        boolean stripZeros = true;
        for( int i = usedChars; i < chars.length; i++) {
            //not a digit, this isn't a simple integer, stop processing and keep the original string
            if( chars[i] < '0' || chars[i] > '9') {
                return s;
            }
            
            //are we still in zero-stripping mode
            if( stripZeros) {
                if( chars[i] == '0') {
                    continue; //check next char
                }
                
                //we've found a non-zero char, keep it and end zero-stripping mode
                if(chars[i] >= '1' && chars[i] <= '9') {
                    stripZeros = false;
                }
            }
            
            //since we are ignoring leading zeros, we just move all digits of the actual number to the left
            chars[usedChars++] = chars[i];                  
        }
        
        //handle special case of number 0 (with optional sign)
        if( usedChars == (hasSign ? 1 : 0)) {
            chars[0] = '0';
            usedChars = 1;
        }
        
        return new String(chars,0, usedChars);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多