Python/2.7 simple coding(+ c++)

string, regular expression관련.

qkqhxla1 2016. 9. 29. 11:20

1. substr


ex) ,를 기준으로 두개로 나누고 싶다.

#include <string>
#include <iostream>
using namespace std;

int main() 
{
	string a="abcd,ef", b, c;
	b = a.substr(0,a.find(',')); //0부터 ,위치까지.
	c = a.substr(a.find(',')+1); //인자를 하나만 주면 여기부터 끝까지.
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
    return 0;
}

2. split함수. 필요해보여서 만들었다.

#include <string>
#include <iostream>
#include <vector>
using namespace std;
 
vector<string> split(string str, string s)
{
    vector<string> ret;
    string after = str, before;
    while(1)
    {
        before = after.substr(0,after.find(s));
        after = after.substr(after.find(s)+s.length());
        /*cout<<"before = "<<before<<endl;
        cout<<"after = "<<after<<endl;
        cout<<"c = "<<after.compare(before)<<endl;
		cout<<after.find(s)<<" "<<after.find(s)+s.length()<<endl<<endl;*/
        ret.push_back(before);
		if(after.compare(before)==0 || after=="" || after.find(s) > str.length())
		{
			ret.push_back(after);
            break;
		}
    }
    return ret;
}
 
int main() 
{
    string a="abc,defghij,klmnopqrs,u";
    vector<string> s = split(a,","); 
	//첫번째 인자는 나눌 string, 두번째 인자는 기준으로 할 string.
    //split된 string들이 들어간 vector를 리턴한다.
    cout<<"원본 = "<<a<<endl;
    for(int i=0;i<s.size();i++)
        cout<<i<<" = "<<s[i]<<endl;
    cout<<endl;
 
    string a1="가나다()라마바()사아자()차";
    vector<string> s1 = split(a1,"()"); 
	//원본 문자열로 한글이나 여러 개의 문자열도 구분자로 쓸수 있다.
    cout<<"원본 = "<<a1<<endl;
    for(int i=0;i<s1.size();i++)
        cout<<i<<" = "<<s1[i]<<endl;
     
    return 0;
}

3. count, isdigit, isalpha, upper, lower 구현

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int count(string original, string find)
{
	int ret=0;
	for(int i=0;i<original.length();i++)
	{
		int c = 0;
		bool flag = true;
		for(int j=0;j<find.length();j++)
		{
			if(original[i+c] != find[j])
				flag = false;
			c++;
		}
		if(flag) ret++;
	}
	return ret;
}
bool isdigit(string original,int index)
{
	if(original[index]>='0' && original[index]<='9')
		return true;
	return false;
}
bool isalpha(string original,int index)
{
	if((original[index]>='A' && original[index]<='Z')
	|| (original[index]>='a' && original[index]<='z'))
		return true;
	return false;
}
string upper(string original)
{
	string ret;
	for(int i=0;i<original.length();i++)
	{
		if(original[i]>='a' && original[i]<='z')
			ret += original[i] - 32;
		else ret += original[i];
	}
	return ret;
}
string lower(string& original)
{
	string ret;
	for(int i=0;i<original.length();i++)
	{
		if(original[i]>='A' && original[i]<='Z')
			ret += original[i] + 32;
		else ret += original[i];
	}
	return ret;
}

int main()
{
	string a="abcdea12345";
	string b = upper(a);
	cout<<b<<endl;
	string c = lower(b);
	cout<<c<<endl;
	cout<<isalpha("abcd",1)<<endl;
	cout<<isdigit("ab12",1)<<endl;
	cout<<count("aabbacabbabc","ab")<<endl;
}

4. 정규표현식 re.split.

#include <string>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <regex>
using namespace std;

vector<string> resplit(const std::string & s, std::string rgx_str = "\\s+") {
	std::vector<std::string> elems;
	std::regex rgx (rgx_str);
	std::sregex_token_iterator iter(s.begin(), s.end(), rgx, -1);
	std::sregex_token_iterator end;

	while (iter != end)  {
		//std::cout << "S43:" << *iter << std::endl;
		elems.push_back(*iter);
		++iter;
	}
	return elems;
}

int main() 
{
	string s222 = "first|second:third,forth";
	vector<string> v222 = resplit(s222, "[|:,]"); //|또는 :또는 ,로 나누겠다.

	for (const auto & e: v222) {
		cout <<"Token:" << e << endl;
	}
	return 0;
}

5. 정규표현식. 


파이썬과 비슷하다. 영어는 쉬우므로 한글 다루는 예제를 올림.


주의 : 스페이스가 \s인데 이걸 정규식에 넣으려면 \\s를 넣어야함. 일부 \가 필요한건 두개쓰기.

#include <string>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <regex>
using namespace std;

int main() 
{
	string pat1 = "[ㄱ-힣]*:(.*)"; //[ㄱ-힣]은 한글 전체를 뜻함. 
    regex pattern1(pat1);    
    string str1("가나다:abcd"); //이 문자열에서 위의 패턴을 찾겠다.
 
    vector<int> v1;
	for(int i=0;i<1;i++) //i<1까지인데 여기서의 1은 위의 패턴에서 괄호갯수를 뜻한다고 함. (.*)로 한개이므로 1.
		v1.push_back(i+1);
 
    int index1 = 0;
    const sregex_token_iterator end1;
 
    for (sregex_token_iterator i1(str1.begin(), str1.end(), pattern1, v1); i1 != end1; )      
    {          
        cout << ++index1 << "번째 : " << *i1++ << endl;
    }
    return 0;
}

6. 정규식 re_findall() 구현

#include <string>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <regex>
#include <vector>
using namespace std;
 
vector<string> re_findall(string str, string pattern, int n)
{
	vector<string> ret;
    regex pattern1(pattern);
	
    vector<int> v;
    for(int i=0;i<n;i++) 
        v.push_back(i+1);
  
    int index = 0;
    const sregex_token_iterator end1;
  
    for (sregex_token_iterator i(str.begin(), str.end(), pattern1, v); i != end1; )      
    {          
		ret.push_back(*i++);
    }
	return ret;
}

int main() 
{
	string str = "ㄹ1번, ㅁ5번, 하하18번";
	string pattern = "[ㄱ-힣]*(\\d+)";
	int n = 1;

	vector<string> f_string = re_findall(str, pattern, n);
	for(int i=0;i<f_string.size();i++)
		cout<<i<<" = "<<f_string[i]<<endl;
    return 0;
}