Pogledajte određenu poruku
Staro 16. 02. 2012.   #1
morando
nedovoljno naspavan
Na probnom radu
 
Datum učlanjenja: 25.03.2011
Poruke: 21
Hvala: 7
1 "Hvala" u 1 poruci
morando is on a distinguished road
Default [C++] Regular expression i ćirlična slova

Problem je sledeći:
Hoću da "uzmem" sve "unikatne" reči iz teksta i izračunam koliko puta se pojavljuju u istom.
Iskopirao sam neke naše poslovice (ćiriličnim slovima pisane) i sačuvao sa notepad-om kao UTF8 fajl. Onda sam priključio UTF8 biblioteku (od autora "Dragi Tata" koji je član ovog foruma, ne mogu sad da nađem pravo ime i prezime ) da izkonvertujem taj text iz UT8 u UTF16 (std::wstring) i pokrenem regex na to:
(win7, VS 2010 C++)
Kôd:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <regex>
#include <limits>
#include <locale>
#include "utf8.h"

int main()
{
	try
	{
		std::ifstream in_file("file.txt");

		std::vector<std::wstring> v_utf16_lines;
		std::string line;
		while(std::getline(in_file, line))
		{
			std::wstring utf16line;
			utf8::utf8to16(line.begin(), line.end(), std::back_inserter(utf16line));
			v_utf16_lines.push_back(utf16line);
		}

		in_file.close();

		//std::wregex::flag_type reg_flags = std::regex_constants::ECMAScript;

		std::set<std::wstring> s_words;
		for(std::size_t i = 0; i < v_utf16_lines.size(); ++i)
		{
			std::wregex pattern(L"\\b[\\p{L}]+\\b");
			const std::wsregex_token_iterator end;
			std::wsregex_token_iterator ti(v_utf16_lines[i].begin(), v_utf16_lines[i].end(), pattern);
			for(; ti != end; ++ti)
			{
				s_words.insert(*ti);
			}
		}

		std::string out_str;

		std::set<std::wstring>::iterator send = s_words.end();
		std::set<std::wstring>::iterator sit = s_words.begin();
		for(; sit != send; ++sit)
		{
			std::size_t w_freq = 0;
			std::wregex pattern(L"\\b" + (*sit) + L"\\b");

			for(std::size_t i = 0; i < v_utf16_lines.size(); ++i)
			{
				const std::wsregex_token_iterator end;
				std::wsregex_token_iterator ti(v_utf16_lines[i].begin(), v_utf16_lines[i].end(), pattern);
				for(; ti != end; ++ti)
				{ ++w_freq; }
			}

			std::string utf8_line;
			utf8::utf16to8((*sit).begin(), (*sit).end(), std::back_inserter(utf8_line));

			out_str += "Word \"";
			out_str += utf8_line;
			out_str += "\", freq = ";
			std::stringstream conv;
			conv << w_freq;
			std::string sfreq;
			conv >> sfreq;
			out_str += sfreq;
			out_str += '\n';
		}

		std::ofstream out_file("result.txt", std::ios::binary);
		out_file.write(out_str.c_str(), out_str.size());
		out_file.close();

	}
	catch(const std::exception& e)
	{
		std::cout << e.what() << std::endl;
	}

    std::cout << "Press enter to exit..." << std::endl;
    std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
    return 0;
}
Evo i slike koja pokazuje da je konverzija uspela:


Na boldiranom delu iz koda dobijam regex exception, ali patern bi trebao da bude standardan/regularan, ne razumem WTF?
Kôd:
std::wregex pattern(L"\\b[\\p{L}]+\\b");
Ovo bi trebalo da pokupi sve reči?

Hvala unapred za ideje.

Poslednja izmena od morando : 16. 02. 2012. u 22:36.
morando je offline   Odgovorite uz citat