从字符串中替换非ASCII字符

时间:2011-12-15 11:51:26

标签: java regex

我有字符串A funçãoÃugent我需要用空字符串替换çãÃ等字符。

如何只匹配那些非ASCII字符?

我正在使用一个功能

public static String matchAndReplaceNonEnglishChar(String tmpsrcdta)
    {
        String newsrcdta = null;
        char array[] = Arrays.stringToCharArray(tmpsrcdta);
        if (array == null)
            return newsrcdta;

        for (int i = 0; i < array.length; i++)
        {           
            int nVal = (int)array[i];
            boolean bISO = Character.isISOControl(array[i]); // Is character ISO control
            boolean bIgnorable = Character.isIdentifierIgnorable(array[i]); // Is Ignorable identifier
            // Remove tab and other unwanted characters..
            if (nVal == 9 || bISO || bIgnorable)
                array[i] = ' ';
            else if (nVal > 255)
                array[i] = ' ';
        }
        newsrcdta = Arrays.charArrayToString(array);

        return newsrcdta;
    }

但它没有正常工作......需要改进...这里我还有一个问题是最后的字符串被空格字符替换,这会在字符串中创建额外的空格。

8 个答案:

答案 0 :(得分:140)

这将搜索并替换所有非 ASCII 字母:

String resultString = subjectString.replaceAll("[^\\x00-\\x7F]", "");

答案 1 :(得分:65)

FailedDev的答案很好,但可以改进。如果要保留ascii等效项,则需要先进行规范化:

String subjectString = "öäü";
subjectString = Normalizer.normalize(subjectString, Normalizer.Form.NFD);
String resultString = subjectString.replaceAll("[^\\x00-\\x7F]", "");

=> will produce "oau"

这样,像“öäü”这样的字符将映射到“oau”,这至少可以保留一些信息。如果没有规范化,结果字符串将为空。

答案 2 :(得分:19)

这将是Unicode解决方案

String s = "A função, Ãugent";
String r = s.replaceAll("\\P{InBasic_Latin}", "");

\p{InBasic_Latin}是Unicode块,包含Unicode范围U + 0000..U + 007F中的所有字母(请参阅regular-expression.info

\P{InBasic_Latin}是否定的\p{InBasic_Latin}

答案 3 :(得分:2)

你可以尝试这样的事情。字母的特殊字符范围从192开始,因此您可以在结果中避免使用此类字符。

String name = "A função";

StringBuilder result = new StringBuilder();
for(char val : name.toCharArray()) {
    if(val < 192) result.append(val);
}
System.out.println("Result "+result.toString());

答案 4 :(得分:0)

或者您可以使用以下函数从字符串中删除非ascii字符。 你会知道内部工作。

private static String removeNonASCIIChar(String str) {

        StringBuffer buff = new StringBuffer();
        char chars[] = str.toCharArray();

        for (int i = 0; i < chars.length; i++) {

            if (0 < chars[i] && chars[i] < 127) {

                buff.append(chars[i]);
            }

        }
        return buff.toString();

    } 

答案 5 :(得分:0)

[更新的解决方案]

可以与“规范化”(规范分解)和“ replaceAll”一起使用,以将其替换为适当的字符。

import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.regex.Pattern;

public final class NormalizeUtils {

    public static String normalizeASCII(final String string) {
        final String normalize = Normalizer.normalize(string, Form.NFD);

        return Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
                      .matcher(normalize)
                      .replaceAll("");
    } ...

答案 6 :(得分:0)

如果您使用的是CharMatcher.retainFrom库,则可以使用

Google Guava

String s = "A função";
String stripped = CharMatcher.ascii().retainFrom(s);
System.out.println(stripped); // Prints "A funo"

答案 7 :(得分:0)

ASCII表包含128个代码,一共95个printable characters,其中只有52个字符是字母:

  • [0-127] ASCII 码
    • [32-126] 可打印字符
      • [48-57] 位数字 [0-9]
      • [65-90] 大写字母 [A-Z]
      • [97-122] 小写字母 [a-z]

您可以使用 String.codePoints 方法获取此字符串的 int 个字符值和 filter非 ASCII 字符的流:

String str1 = "A função, Ãugent";

String str2 = str1.codePoints()
        .filter(ch -> ch < 128)
        .mapToObj(Character::toString)
        .collect(Collectors.joining());

System.out.println(str2); // A funo, ugent

或者您可以显式指定字符范围。例如过滤掉除字母之外的所有内容

String str3 = str1.codePoints()
        .filter(ch -> ch >= 'A' && ch <= 'Z'
                || ch >= 'a' && ch <= 'z')
        .mapToObj(Character::toString)
        .collect(Collectors.joining());

System.out.println(str3); // Afunougent

另见:How do I not take Special Characters in my Password Validation (without Regex)?