2015-08-14 63 views
2

如何使用正则表达式替换下划线字符的每个数字开头的字符,以及该字的其余部分以替换除字母,数字,短划线和点之外的所有字符强调?Java正则表达式替换开始的每个数字

我想这正则表达式:

^(\d+)|[^\w-.] 

然而,它取代所有数字在一开始与一个下划线。

所以,当我需要在开始的每一位数字与像_____fgf-kl.___676hh一个下划线代替34567fgf-kl.)*/676hh转化为_fgf-kl.___676hh

使用正则表达式可以实现吗?

+0

请提供您要选择 –

+0

什么一些例子有谁知道如何'[^ \ W - ]'被处理?我正要告诉nau他有一个错误,但我发现这确实有效。它将匹配任何不是单词字符,连字符或圆点的内容。我可以发誓它会尝试匹配任何不在“单词字符”和“点”范围之间的任何内容(我认为这是一个空集) - 你知道,比如'[a-z]'。 – DavidS

+0

@DavidS:没有错误,因为连字符不能在字符类内的速记类之前或之后被解析为范围说明符。在这种情况下,它总是被视为文字。但是,在我的回答中,我像往常一样把它放在最后。只是玩双安全。 –

回答

3

您可以用Matcher.find使用Matcher.appendReplacement做这样的:

String fileText = "34567fgf-kl.)*/676hh"; 
String pattern = "^\\d+|[^\\w.-]+"; 

Pattern r = Pattern.compile(pattern); 
Matcher m = r.matcher(fileText); 

StringBuffer sb = new StringBuffer(); 
while (m.find()) { 
    m.appendReplacement(sb, repeat("_", m.group(0).length())); 
} 
m.appendTail(sb); // append the rest of the contents 
System.out.println(sb); 

而且repeat

public static String repeat(String s, int n) { 
    if(s == null) { 
     return null; 
    } 
    final StringBuilder sb = new StringBuilder(s.length() * n); 
    for(int i = 0; i < n; i++) { 
     sb.append(s); 
    } 
    return sb.toString(); 
} 

IDEONE demo

此外,repeat可以使用Commons Lang StringUtils.repeat()String repeated = StringUtils.repeat("_", m.group(0).length());被替换。

0

您可以使用负向lookbehind单独匹配每个前导数字,即任何在其之前没有非数字的数字。

(?<!\D.{0,999})\d|[^\w-.] 

由于后视限制,它不能无限制。上面的代码最多可以处理999个前导数字。

0

您还可以使用replaceAll()用正则表达式:

(^\d)|(?<=\d\G)\d|[^-\w.\n] 

这意味着匹配:

  • (^\d) - 数字一行的开头,
  • | - 或
  • (?<=\d\G)\d - 位如果它之前是以前匹配的数字,
  • | - 或
  • [^-\w.\n] - 不冲,字字符(\w[A-Za-z_0-9]),点或 新线(\n)。作为一个[^-\w.\n]是相当广泛的类别,也许你会喜欢添加一些更多的字符,或字符组,从匹配排除,就足以将它添加括号内,

DEMO

\n添加如果字符串可能是多行的。如果只有一行字符串,则\n是多余的。

实例中的Java:

public class Test { 
    public static void main(String[] args) { 
     String example = "34567fgf-kl.)*/676hh"; 
     System.out.println(example.replaceAll("(^\\d)|(?<=\\d\\G)\\d|[^\\w.-]", "_")); 
    } 
} 

与输出:

_____fgf-kl.___676hh