gpt4 book ai didi

c++ - 处理带有奇怪字符的文本

转载 作者:行者123 更新时间:2023-11-28 00:13:26 26 4
gpt4 key购买 nike

我有一个由句子组成的文本语料库,每行一个。语料库是德语的,其中的某些部分包含一些奇怪的字符。例如,当从终端使用 less 命令查看时,以下是一些行:

w�hlen sie die zahlen aus, indem sie sie anklicken. sie k�nnen f�r jede runde zwei bis zehn zahlen ausw�hlen.

keno xperiment ist eine erweiterte version vom keno lottery spiel.

nachdem sie ihre auswahl getroffen haben, klicken sie auf eine spielen, um die spielrunde zu starten, oder auf f�nf spielen, um mit den ausgew�hlten zahlen f�nf runden hintereinander zu spielen.

unter dem hauptspielbereich finden sie eine reihe von buttons mit den zahlen 2 bis 10, au�erdem die zufallsauswahl und ein k�stchen mit der bezeichnung �vor jeder runde neue zahlen ausw�hlen�.

(‘�’其实就是带元音变音的字符。令人惊讶的是,在某些行中,这些字符显示得非常完美)

我想处理以去除包含这些损坏字符的行。这是代码:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <pthread.h>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>

using namespace std;

int lengthLowerBound = -1;
int requirePunct = 0;

unordered_map <string, string> specials;

// weird characters
#pragma warning( push)
#pragma warning( disable : 4101 )
bool isOK(char ch) {
if (ch == '�') return false;
return true;
}
#pragma warning( pop )

bool isOK(string &line) {
for (int i = 0; i < line.length(); ++i) {
if (line[i] == '�') return false;
}
return true;
}

// has punctuations
bool hasPunctuations(string &line) {
for (int i = 0; i < line.length(); ++i) {
if (ispunct(line[i])) return true;
}
return false;
}

int main(int argc, char *argv[]) {
if (argc < 5) {
cout << "Usage: ./Filter input1.txt input2.txt output1.txt output2.txt [hasPunctuation | noShorterThan x]" << endl;
exit(1);
}

string inpFile1 = string(argv[1]);
string inpFile2 = string(argv[2]);
string outFile1 = string(argv[3]);
string outFile2 = string(argv[4]);

for (int i = 5; i < argc; ++i) {
if (strcmp(argv[i], "hasPunctuation") == 0) requirePunct = 1;
else if (strcmp(argv[i], "noShorterThan") == 0) lengthLowerBound = atoi(argv[i+1]);
}

// filter
ifstream finp1(inpFile1, ifstream::in);
if (finp1.fail()) {
cout << " Can't open file " << inpFile1 << endl;
exit(1);
}

ifstream finp2(inpFile2, ifstream::in);
if (finp2.fail()) {
cout << " Can't open file " << inpFile2 << endl;
exit(1);
}

ofstream fout1(outFile1, ofstream::out);
if (fout1.fail()) {
cout << " Can't open file " << outFile1 << endl;
exit(1);
}

ofstream fout2(outFile2, ofstream::out);
if (fout2.fail()) {
cout << " Can't open file " << outFile2 << endl;
exit(1);
}

string line1, line2;
int numLines = 0;
cout << "# Start tokenizing" << endl;
while (getline(finp1, line1)) {
getline(finp2, line2);

if (line1.empty() || line2.empty()) continue;

if (!isOK(line1) || !isOK(line2)) continue;

if (lengthLowerBound > 0) {
if (line1.length() < lengthLowerBound || line2.length() < lengthLowerBound) continue;
}

if (requirePunct) {
if (!hasPunctuations(line1) || !hasPunctuations(line2)) continue;
}

fout1 << line1 << endl;
fout2 << line2 << endl;

++numLines;
if (numLines % 1000 == 0) cout << "\r Read " << numLines/1000 << "k lines.";
}
cout << endl;
cout << "# Done" << endl;

fout2.close();
fout1.close();
finp2.close();
finp1.close();

return 0;
}

如果您只是复制上面的代码并按照代码本身的指导使用适当的命令运行它,在给定的句子上,您会看到代码没有执行任何操作。我怀疑这是因为比较 ch == '�' 总是错误的。实际上有一个警告。

那么,我的问题是如何做我想做的事?而且它不需要在 C++ 中。高度赞赏 Python、Perl 或 sed 命令,任何东西。谢谢。

TL;DR:我想处理一个文本文件以去除引用文本中的所有“�”字符。

最佳答案

看起来 less 不理解您的德语文件的编码:“�”字符可能因此显示在实际字符的位置。过滤掉这些行的最简单方法可能是通过查看是否有任何字节设置了最高位来检查非 ASCII 字符:

bool isOk(const string& line) {
return none_of(begin(line), end(line), [](uint8_t c) {return 0x80 & c;});
}

这适用于 UTF-8 编码文本,因为任何非 ASCII 代码点都被编码为多个字节,每个字节都设置了最高位。它也适用于更有限的 8 位代码,如 ISO-8859-1,因为非 ASCII 字符由 ASCII 范围之外的字节表示,这些字节也必须设置最高位。

关于c++ - 处理带有奇怪字符的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31867706/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com