从Java中的字符串中删除所有非单词字符,留下带重音符号的字符?


68

显然,当我使用Regex时,Java的Regex风格将Umlauts和其他特殊字符视为非“单词字符”。

        "TESTÜTEST".replaceAll( "\\W", "" )

为我返回“ TESTTEST”。我想要的是仅删除所有真正的非“单词字符”。无需采取任何措施即可执行此操作的任何方法

         "[^A-Za-z0-9äöüÄÖÜßéèáàúùóò]"

才意识到我忘记了?


Answers:


159

采用 [^\p{L}\p{Nd}]+-匹配所有既不是字母也不是(十进制)数字的(Unicode)字符。

在Java中:

String resultString = subjectString.replaceAll("[^\\p{L}\\p{Nd}]+", "");

编辑:

我更改\p{N}为,\p{Nd}因为前者还匹配一些数字符号,例如¼;后者没有。在regex101.com查看


1
为什么\\[在角色类里面?
巴特·基尔斯

2
奇迹般有效!但不替换“º”,“ª”,“¼”。因为我只有这个“º”,所以我使用了.replaceAll(“ [^ \\ p {L} \\ p {N}] |º”,“”); 关于如何删除别人的任何建议?
user952887 2011年

3
对常见\W问题提出非常有用的答案。
zx81

@TimPietzcker,请您帮我解决这个stackoverflow.com/questions/23797093/…–
Axel

如何删除数字和数字(仅保留字母)?
Francisco Corrales Morales 2014年

7

当我碰到这个线程时,我试图达到完全相反的目的。我知道它已经很老了,但是这仍然是我的解决方案。您可以使用块,请参见此处。在这种情况下,请编译以下代码(带有正确的导入):

> String s = "äêìóblah"; 
> Pattern p = Pattern.compile("[\\p{InLatin-1Supplement}]+"); // this regex uses a block
> Matcher m = p.matcher(s);
> System.out.println(m.find());
> System.out.println(s.replaceAll(p.pattern(), "#"));

您应该看到以下输出:

真正

#blah

最好,


6

有时您不想简单地删除字符,而只是删除重音符号。我想出了以下实用程序类,当我需要在URL中包含String时,将在Java REST Web项目中使用该实用程序类:

import java.text.Normalizer;
import java.text.Normalizer.Form;

import org.apache.commons.lang.StringUtils;

/**
 * Utility class for String manipulation.
 * 
 * @author Stefan Haberl
 */
public abstract class TextUtils {
    private static String[] searchList = { "Ä", "ä", "Ö", "ö", "Ü", "ü", "ß" };
    private static String[] replaceList = { "Ae", "ae", "Oe", "oe", "Ue", "ue",
            "sz" };

    /**
     * Normalizes a String by removing all accents to original 127 US-ASCII
     * characters. This method handles German umlauts and "sharp-s" correctly
     * 
     * @param s
     *            The String to normalize
     * @return The normalized String
     */
    public static String normalize(String s) {
        if (s == null)
            return null;

        String n = null;

        n = StringUtils.replaceEachRepeatedly(s, searchList, replaceList);
        n = Normalizer.normalize(n, Form.NFD).replaceAll("[^\\p{ASCII}]", "");

        return n;
    }

    /**
     * Returns a clean representation of a String which might be used safely
     * within an URL. Slugs are a more human friendly form of URL encoding a
     * String.
     * <p>
     * The method first normalizes a String, then converts it to lowercase and
     * removes ASCII characters, which might be problematic in URLs:
     * <ul>
     * <li>all whitespaces
     * <li>dots ('.')
     * <li>(semi-)colons (';' and ':')
     * <li>equals ('=')
     * <li>ampersands ('&')
     * <li>slashes ('/')
     * <li>angle brackets ('<' and '>')
     * </ul>
     * 
     * @param s
     *            The String to slugify
     * @return The slugified String
     * @see #normalize(String)
     */
    public static String slugify(String s) {

        if (s == null)
            return null;

        String n = normalize(s);
        n = StringUtils.lowerCase(n);
        n = n.replaceAll("[\\s.:;&=<>/]", "");

        return n;
    }
}

作为讲德语的人,我还包括对德语变音符号的正确处理-该列表应该易于扩展到其他语言。

高温超导

编辑:请注意,将返回的字符串包含在URL中可能是不安全的。您至少应该对其进行HTML编码,以防止XSS攻击。


重要信息,您可以获取StringUtils类/包等。@ commons.apache.org/lang/download_lang.cgi
cV2 2011年

你从来没用过slugify

@Starslugify是在其余代码中使用的公共实用程序方法。
Stefan Haberl

2

好吧,这是我最终得到的一个解决方案,但我希望有一个更优雅的解决方案...

StringBuilder result = new StringBuilder();
for(int i=0; i<name.length(); i++) {
    char tmpChar = name.charAt( i );
    if (Character.isLetterOrDigit( tmpChar) || tmpChar == '_' ) {
        result.append( tmpChar );
    }
}

result 最终获得理想的结果...


1
您的变量String被命名的事实name表明它不会是一个很大的String。但是,如果确实变大(成千上万个字符),我会像您现在一样使用for语句。
巴特·基尔斯

1

您可能要先删除重音符号和变音符号,然后在每个字符位置检查“简体”字符串是否为ascii字母-如果是,则原始位置应包含单词字符,如果不是,则可以将其删除。


android API级别9之前不支持java.text.Normalizer类,因此,如果您的应用必须与API级别8兼容(根据Google的Android信息中心,占设备总数的13%),则此方法不可行
Giorgio Barchiesi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.