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