【问题标题】:Replace underscore between words (reg.exp)替换单词之间的下划线 (reg.exp)
【发布时间】:2010-03-08 17:53:41
【问题描述】:

我需要一个正则表达式来解决以下问题(类似问题的链接也很感激,相关教程等):

"__some_words_a_b___" => "__some words a b___"
"____" => "____"
"some___words" => "some   words"

所以我想用空格替换单词之间的下划线,并保持前导和尾随下划线。我发现了这个:

^[ \t]+|[ \t]+$

而且我猜它大多是这样的。我将在 jQuery、Java (stdlibs) 和 XSLT 中使用它。

补充: 句子不一定以下划线开头或以下划线结尾。句子也可能根本不包含下划线。多个下划线应该渲染到多个空格

最好的问候 拉塞·埃斯佩霍尔特

【问题讨论】:

    标签: java jquery regex xslt replace


    【解决方案1】:

    这应该在 Javascript 中工作:

    var newString = oldString.replace(/([^_].*?)_(?=[^_|^\s])/g,"$1 ");
    

    编辑:如果字符串中已经有空格,可能需要添加这样的内容:

    var newString = oldString.replace(/([^_|\s].*?)_(?=[^_|^s])/g,"$1 ");
    

    我忘记了任何其他边缘情况? :) 哦,是的,另一个极端情况。如果后跟空格(如换行符、行尾等),请保留结尾的下划线。

    edit:如果单词之间的下划线数量>1

    的替代解决方案
    var arrayString = oldString.replace(/^(_+)(.*?)(_+)$/g,"$1;$2;$3");
    var a = arrayString.split(";");
    var newString = a[0]+a[1].replace(/_/g," ")+a[2];
    

    【讨论】:

    • 最后一个几乎可以工作 :) 但是如果句子是 test__test 则剩下一个下划线。我试过这个: ([^_|\s].*?)_+(?=[^_]) 但它用一个空格替换了两个下划线
    • 如果是这种情况,您将需要两个替换方法。
    • 很公平 :) ([^_|\s].*?)_+(?=[^_]) 会做的,谢谢你的时间:)
    【解决方案2】:

    我认为使用正则表达式和字符串替换会更简单。这是 Python 中的答案,因为我对 jQuery、Java 或 XSLT 不够熟悉:

    import re
    
    def mangle_string(string):
        """
        Replace underscores between letters with spaces, leave leading and
        trailing underscores alone.
        """
        # Match a string that starts with zero or more underscores, followed by a
        # non-underscore, followed by zero or more of any characters, followed by
        # another non-underscore, followed by zero or more underscores, then the
        # end of the string.  If the string doesn't match that pattern, then return
        # it unmodified.
        m = re.search(r'^(_*)([^_]+.*[^_]+)(_*)$', string)
        if not m:
            return string
        # Return the concatentation of first group (the leading underscores), then
        # the middle group (everything else) with any internal underscores
        # replaced with spaces, then the last group (the trailing underscores).
        return m.group(1) + m.group(2).replace('_', ' ') + m.group(3)
    

    【讨论】:

    • 这个想法是我希望我的方法保持一致。是否可以创建一个替换字符串来执行您在 return 语句中所做的操作?
    • 可能,但我认为它不会那么简单(而且它的性能很可能不如字符串替换)。
    【解决方案3】:

    也许这就是你想要的(Javascript):

    var newString = oldString.replace(/(\w)_(\w)/g, "$1 $2");
    

    如果单词之间可以有很多下划线,那么:

    var newString = oldString.replace(/(\w)_+(\w)/g, "$1 $2");
    

    如果您想保留与下划线相同数量的空格:

    var newString = oldString.replace(/(\w)(_+)(\w)/g, function(_, l1, u, l2) {
      return l1 + (u.length == 1 ? ' ' : (new Array(u.length - 1).join(' '))) + l2;
    });
    

    【讨论】:

    • 感谢您的贡献 :) 但“hej_med_dig”呈现为“_ hej med dig _”
    【解决方案4】:

    我不会为此使用正则表达式。我将计算前导和尾随下划线,然后将前导子字符串(如果有)与middle.replace('_',' ') 和尾随子字符串(如果有)连接起来。如果前导下划线运行到末尾,则立即返回原始字符串。

    【讨论】:

    • 它确实要快得多,但在这些语言中,它需要一些代码来完成。而在 XSLT 中,我更喜欢 reg.exp。就我而言,性能不是问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2017-08-08
    • 2011-03-06
    • 2023-03-18
    • 2016-01-15
    相关资源
    最近更新 更多