有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (6) 个答案

  1. # 1 楼答案

    免责声明

    因为有几个答案已经提到了字符串构建器的更高效率,所以我想向您展示如何使用regex实现它,并说明使用这种方法的好处

    一个正则表达式解决方案

    使用此匹配的正则表达式(类似于Alan Moore's expression):

    (.{3})(.{3})(.{4})
    

    允许您将10个字符精确匹配到3个组中,然后使用引用这些组的替换表达式,并添加其他字符:

    ($1) $2-$3
    

    从而按照您的要求生产替换件。当然,它还将匹配标点和字母,这也是使用\d(作为\\d编码到Java字符串中)而不是.通配符的原因

    为什么是正则表达式

    正则表达式方法的潜在优势是将“逻辑”压缩到字符串操作中。由于所有的“逻辑”都可以压缩成字符串,而不是预编译的代码,因此正则表达式匹配和替换字符串可以存储在数据库中,以便有经验的系统用户更容易操作、更新或自定义。这使得情况在多个层面上更加复杂,但为用户提供了更大的灵活性

    使用其他方法(字符串操作),仅通过用户界面根本不可能更改格式化算法,从而生成(555)123-4567555.123.4567而不是指定的(555) 123-4567。使用regex方法,修改将非常简单,只要将($1) $2-$3(在数据库或类似存储中)适当地更改为$1.$2.$3($1)$2-$3

    如果您想修改您的系统以接受“dirtier”输入,这可能包括各种格式化尝试,例如555-123.4567,并将其重新格式化为一致的格式,那么可以制作一个能够实现这一点的字符串操作算法,并重新编译应用程序,使其按照您的意愿工作。然而,对于正则表达式解决方案,不需要进行系统大修——只需像这样更改解析和替换表达式(对于初学者来说可能有点复杂,需要立即理解):

    ^\D*1?\D*([2-9])\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d)\D*(\d).*$
    ($1$2$3) $4$5$6-$7$8$9$10
    

    这将允许对程序的能力进行重大的“升级”,如以下重新格式化所示:

    "Input"                       "Output"
    ----------------------------- --------------------------------
    "1323-456-7890 540"           "(323) 456-7890"
    "8648217634"                  "(864) 821-7634"
    "453453453322"                "(453) 453-4533"
    "@404-327-4532"               "(404) 327-4532"
    "172830923423456"             "(728) 309-2342"
    "jh345gjk26k65g3245"          "(345) 266-5324"
    "jh3g24235h2g3j5h3"           "(324) 235-2353"
    "12345678925x14"              "(234) 567-8925"
    "+1 (322)485-9321"            "(322) 485-9321"
    "804.555.1234"                "(804) 555-1234"
    "08648217634"                 <no match or reformatting>
    

    正如您所看到的,它对输入“格式化”非常“宽容”,并且知道1应该在数字的开头被忽略,并且0应该会导致错误,因为它是无效的-所有存储在单个字符串中

    问题归结为性能与定制潜力。字符串操作比正则表达式快,但未来的增强自定义需要重新编译,而不是简单地更改字符串。这就是说,有些东西不能很好地表达(甚至不能像上面的更改那样可读),有些东西在regex中是不可能的

    TL;医生:

    Regex允许将解析算法存储到一个相对较短的字符串中,该字符串可以轻松存储,以便无需重新编译即可修改。更简单、更集中的字符串操作函数更高效,有时可以完成比正则表达式更多的任务。关键是要了解应用程序的工具和需求,并使用最适合这种情况的工具

  2. # 2 楼答案

    带有子字符串的StringBuilder将更快,但并不总是最简单/最好的方法。在这种情况下,我将只使用子字符串

    String num = "1234567890";
    String formatted = "(" + num.substring(0,3) + ") "
         + num.substring(3,6) + "-" + num.substring(6); 
    
  3. # 3 楼答案

    带有组的正则表达式匹配器实际上只是一些字符串容器,再加上大量重新匹配的代码。(实际上,您可以查看源代码并亲自查看。)这没有比自己使用substring()更便宜的了,尤其是像您这样使用固定偏移量

  4. # 4 楼答案

    当不能使用substring或更难使用时,可以使用RE

    在您的情况下,最好只使用StringBuilderinsert()

    假设电话号码长度验证已到位(=10个字符)

            String phoneNumber = "1234567890";
            StringBuilder sb = new StringBuilder(phoneNumber)
                                    .insert(0,"(")
                                    .insert(4,")")
                                    .insert(8,"-");
            String output = sb.toString();
            System.out.println(output);          
    

    输出

    (123)456-7890
    
  5. # 5 楼答案

    同样的技术也适用于Java;您只需调整Java语法和API:

    s = s.replaceFirst("(\\d{3})(\\d{3})(\\d{4})", "($1) $2-$3");
    

    但我不明白你为什么问更快的方法。您是否尝试过类似的方法并遇到性能问题?几乎可以肯定的是,使用StringBuilder可以更高效地完成这项工作,但实际上,这几乎肯定是不值得的

    或者你是在说,相对于用StringBuilder手工编码,学习如何用正则表达式来实现这一点需要多少时间?不过,这一点现在还没有定论D

  6. # 6 楼答案

    我将结合使用java String.format()方法和String.substring()