【问题标题】:How to convert "string" to "*s*t*r*i*n*g*"如何将“字符串”转换为“*s*t*r*i*n*g*”
【发布时间】:2011-03-18 00:18:03
【问题描述】:

我需要像这样转换一个字符串

"string"

"*s*t*r*i*n*g*"

什么是正则表达式模式?语言是 Java。

【问题讨论】:

    标签: java regex replace string


    【解决方案1】:

    您想匹配一个空字符串,并替换为"*"。所以,这样的事情是有效的:

    System.out.println("string".replaceAll("", "*"));
    // "*s*t*r*i*n*g*"
    

    或者更好的是,因为空字符串可以在没有正则表达式的情况下进行字面匹配,你可以这样做:

    System.out.println("string".replace("", "*"));
    // "*s*t*r*i*n*g*"
    

    为什么会这样

    这是因为字符串startsWith("")endsWith("")contains(""). 的任何实例在任何字符串的任意两个字符之间,都有一个空字符串。事实上,在这些位置有无数个空字符串。

    (是的,对于空字符串本身也是如此。那是一个“空”字符串contains 本身!)。

    在这种情况下,正则表达式引擎和String.replace 在查找下一个匹配项时会自动推进索引,以防止无限循环。


    “真正的”正则表达式解决方案

    没有必要这样做,但这里显示它是为了教育目的:类似这样的东西也有效:

    System.out.println("string".replaceAll(".?", "*$0"));
    // "*s*t*r*i*n*g*"
    

    通过将“任何”字符与. 匹配,并将其替换为* 和该字符,通过反向引用组0 来实现。

    要为最后一个字符添加星号,我们允许. 可选地与.? 匹配。这是可行的,因为? 是贪婪的,如果可能的话,总是会取一个字符,即除了最后一个字符之外的任何地方。

    如果字符串可能包含换行符,则使用Pattern.DOTALL/(?s) 模式。

    参考文献

    【讨论】:

    • 感谢您深入了解其工作原理。你已经赢得了 35k 的声望! :D
    • 不是每个字符串 contains 本身吗?
    【解决方案2】:

    我认为"" 是您想要的正则表达式。

    System.out.println("string".replaceAll("", "*"));
    

    这打印出*s*t*r*i*n*g*

    【讨论】:

    • 那不是正则表达式 ;) replace() 方法进行逐字符替换。在这里,您将“无”替换为 *。真正的正则表达式替换是通过replaceAll() 方法完成的。
    • @BalusC:我想这是一个微妙的暗示,即不需要正则表达式:P
    • 不,这是我的错,但空字符串也可以用作正则表达式。编辑了我的答案,改为使用 replaceAll。
    • 其实,String.replace(CharSequence, CharSequence) uses Pattern` 来做替换。所以,实际上,它是正则表达式:p
    • @TheEliteGentleman:已确认。我的天啊。根本没想到。我想我过去说replace 更快时一直在撒谎。
    【解决方案3】:

    如果这就是你所做的一切,我不会使用正则表达式:

    public static String glitzItUp(String text) {
        return insertPeriodically(text, "*", 1);
    }
    

    Putting char into a java string for each N characters

    public static String insertPeriodically(
        String text, String insert, int period) 
    {
        StringBuilder builder = new StringBuilder(
            text.length() + insert.length() * (text.length()/period)+1);
    
        int index = 0;
        while (index <= text.length())
        {
            builder.append(insert);
            builder.append(text.substring(index,
                Math.min(index + period, text.length())));
            index += period;
        }
        return builder.toString();
    }
    

    另一个好处(除了简单性)是它比正则表达式更接近ten times faster

    IDEOne | Working example

    【讨论】:

    • 小字符串的速度差异是否明显?
    【解决方案4】:

    为了成为一个混蛋,我会说使用 J:

    我花了一个学年学习 Java,并在整个暑假期间自学了一点 J因为整个插入星号的事情很容易通过一个简单的动词定义和一个循环来完成。

    asterisked =: 3 : 0 
     i =. 0
     running_String =. '*'
     while. i < #y do. 
        NB. #y returns tally, or number of items in y: right operand to the verb
        running_String =. running_String, (i{y) , '*'
        i =. >: i
     end.
     ]running_String
    )
    

    这就是我使用 J 的原因:我知道如何做到这一点,并且只松散地学习了几个月的语言。这不像整个 .replaceAll() 方法那样简洁,但您可以自己轻松完成,稍后根据您的规范对其进行编辑。随意删除这个/巨魔这个/对我对 J 的建议感到愤怒,我真的不在乎:我不是在宣传它。

    【讨论】:

    • 那是一些非常难看的代码。抱歉,但是好的旧 Java 代码看起来好多了 imo。
    • 这就是我所说的Java风格的J。真正了解J的人可以用1行J写出整个程序。比较Java和J就像比较秘书。 Java 看起来很漂亮,可以把事情做好,但是冗长而循序渐进。 J 是一个很难看和近乎丑陋的人,但却非常高效和勤奋。
    猜你喜欢
    • 2017-08-01
    • 1970-01-01
    • 2018-12-14
    • 2011-08-19
    • 2018-07-24
    • 2015-03-06
    • 2020-10-15
    • 2020-06-25
    • 1970-01-01
    相关资源
    最近更新 更多