Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一个正则表达式可以(有效地)对它们进行规则化?_Java_Html_Regex_String - Fatal编程技术网

Java 一个正则表达式可以(有效地)对它们进行规则化?

Java 一个正则表达式可以(有效地)对它们进行规则化?,java,html,regex,string,Java,Html,Regex,String,嘿,伙计们,我一直在尝试通过解析HTML文件来从中提取文本,而且每隔一段时间,我就会得到一些非常奇怪的字符,比如和€。我确定是“智能引号”或卷曲的标点符号导致了我所有的问题,所以我的临时解决办法是搜索所有这些字符,并用它们各自对应的HTML代码替换它们。我的问题是,有没有这样一种方法可以使用一个正则表达式(或其他东西)只搜索字符串一次,并根据字符串中的内容替换它所需要的内容?我现在的解决方案如下所示: line = line.replaceAll( "“", "“" ).re

嘿,伙计们,我一直在尝试通过解析HTML文件来从中提取文本,而且每隔一段时间,我就会得到一些非常奇怪的字符,比如
和€
。我确定是“智能引号”或卷曲的标点符号导致了我所有的问题,所以我的临时解决办法是搜索所有这些字符,并用它们各自对应的HTML代码替换它们。我的问题是,有没有这样一种方法可以使用一个正则表达式(或其他东西)只搜索字符串一次,并根据字符串中的内容替换它所需要的内容?我现在的解决方案如下所示:

line = line.replaceAll( "“", "“" ).replaceAll( "”", "”" );
line = line.replaceAll( "–", "–" ).replaceAll( "—", "—" );
line = line.replaceAll( "‘", "‘" ).replaceAll( "’", "’" ); 
出于某种原因,似乎有一种更好、可能更有效的方法可以做到这一点。非常感谢您的任何意见

谢谢,

-Brett不要对HTML使用正则表达式。使用真正的解析器


这也将帮助您避开可能遇到的任何字符编码。

有一个巨大的线程向您展示了为什么使用正则表达式解析HTML是个坏主意


寻找外部库来完成此任务。例如:。他们的网页中还包含一个教程,您可以使用。

您的文件似乎是UTF-8编码的,但您在阅读它时,就好像它是用单字节编码的,如windows-1252。UTF-8使用三个字节对这些字符中的每一个进行编码,但当您将其解码为windows-1252时,每个字节都被视为一个单独的字符

在处理文本时,如果可能,应始终指定编码;不要让系统使用其默认编码。在Java中,这意味着使用InputStreamReader和OutputStreamWriter,而不是FileReader和FileWriter。任何相当好的文本编辑器都应该允许您指定编码

至于您的实际问题,不,Java没有用于动态替换的内置功能(与大多数其他正则表达式风格不同)。但是写自己的并不难,或者更好,用别人写的。我从艾略特·休斯那里发了一封信


最后一件事:在示例代码中,您使用
replaceAll()
进行替换,这是一种过度杀伤力,可能是bug的来源。因为您匹配的是文本而不是正则表达式,所以应该使用
replace(CharSequence,CharSequence)
。这样你就不必担心意外地包含一个regex元字符而变成blooey。

正如其他人所说;处理这些字符的建议方法是配置编码设置

为了进行比较,以下是一种使用正则表达式将UTF-8序列重新编码为HTML实体的方法:

import java.util.regex.*;

public class UTF8Fixer {
    static String fixUTF8Characters(String str) {
        // Pattern to match most UTF-8 sequences:
        Pattern utf8Pattern = Pattern.compile("[\\xC0-\\xDF][\\x80-\\xBF]{1}|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xF7][\\x80-\\xBF]{3}");

        Matcher utf8Matcher = utf8Pattern.matcher(str);
        StringBuffer buf = new StringBuffer();

        // Search for matches
        while (utf8Matcher.find()) {
            // Decode the character
            String encoded = utf8Matcher.group();
            int codePoint = encoded.codePointAt(0);
            if (codePoint >= 0xF0) {
                codePoint &= 0x07;
            }
            else if (codePoint >= 0xE0) {
                codePoint &= 0x0F;
            }
            else {
                codePoint &= 0x1F;
            }
            for (int i = 1; i < encoded.length(); i++) {
                codePoint = (codePoint << 6) | (encoded.codePointAt(i) & 0x3F);
            }
            // Recode it as an HTML entity
            encoded = String.format("&#%d;", codePoint);
            // Add it to the buffer
            utf8Matcher.appendReplacement(buf,encoded);
        }
        utf8Matcher.appendTail(buf);
        return buf.toString();
    }

    public static void main(String[] args) {
        String subject = "String with \u00E2\u0080\u0092strange\u00E2\u0080\u0093 characters";
        String result = UTF8Fixer.fixUTF8Characters(subject);
        System.out.printf("Subject: %s%n", subject);
        System.out.printf("Result: %s%n", result);
    }
}
import java.util.regex.*;
公共类UTF8Fixer{
静态字符串fixUTF8字符(字符串str){
//匹配大多数UTF-8序列的模式:
Pattern utf8Pattern=Pattern.compile(“[\\xC0-\\xDF][\\x80-\\xBF]{1}|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xF7][\\x80-\\xBF]{3}”);
Matcher utf8Matcher=utf8Pattern.Matcher(str);
StringBuffer buf=新的StringBuffer();
//搜索匹配项
while(utf8Matcher.find()){
//解码字符
字符串编码=utf8Matcher.group();
int codePoint=encoded.codePoint(0);
如果(代码点>=0xF0){
码点&=0x07;
}
否则如果(代码点>=0xE0){
码点&=0x0F;
}
否则{
码点&=0x1F;
}
for(int i=1;icodePoint=(codePoint如果你使用UTF-8作为页面编码,你根本不需要任何HTML实体。怎么样?@seanizer,你仍然需要
&;
;)(如果你不关心有效性,有时你可以使用文字字符,但这会导致问题)是的,但这些都是XML实体。我说的是HTML实体好吧,smartass。它们也是HTML实体。哇,在这个线程上升温。为了打破这个论点,我在Java API中使用HTMLEditorKit来进行HTML解析。我需要正则表达式模式来找到这些多字节字符,并用它们各自的字符替换它们实体。我的沟通不是很好,但很好。将某些字符转换为实体并不是用正则表达式解析HTML。“奇怪的字符”看起来像是错误地处理UTF-8。@Thorbjørn,我意识到。这仍然不是解析HTML。@Epiless,op明确地说:“我一直在尝试通过解析HTML文件来从中提取文本。”他正在尝试使用正则表达式解析HTML,因此,他遇到了类似这样的问题。谁知道当推荐的方法是使用外部库时可能会出现什么其他问题。@编码,如果您阅读了代码的话(众所周知,这比它的评论更为正确),您可以看到OP正在替换文本中的字符,而不是解析HTML。它们是解析字符,恰好位于HTML文档中,但实际上没有适用于问题及其解决方案的HTML解析规则。外部库与问题与解析HTM无关这一事实有何关系L标记?将某些字符转换为实体并不是用正则表达式解析HTML。正则表达式是用于特殊的多字节字符,而不是解析我的HTML,但非常感谢JSoup引用——这比Java API HTMLEditorKit要好很多。这条建议昨晚走了很长一段路。在对读者和输入进行了一点挖掘之后treams,我决定为了读者和作者的利益而放弃输入/输出流会更好。谢谢。