aboutsummaryrefslogtreecommitdiff
path: root/src/functionregex.cpp
blob: f0abc357fba95641ab5e9619de72d48fcd8eeb1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "functionregex.h"

#include <bu/regex.h>
#include <bu/plugger.h>
PluginInterface3( pluginFunctionRegEx, regex, FunctionRegEx, Function,
		"Mike Buland", 0, 1 );

FunctionRegEx::FunctionRegEx()
{
}

FunctionRegEx::~FunctionRegEx()
{
}

Bu::FString FunctionRegEx::getName() const
{
	return "regex";
}

Variable FunctionRegEx::call( Variable &input, VarList lParams )
{
	if( lParams.getSize() == 1 )
	{
		Bu::RegEx re( lParams.first().getString() );
		switch( input.getType() )
		{
			case Variable::typeString:
				return re.execute( input.getString() );

			case Variable::typeList:
				{
					Variable vOut( Variable::typeList );
					for( VarList::iterator i = input.begin(); i; i++ )
					{
						if( re.execute( (*i).toString() ) )
							vOut.append( *i );
					}
					return vOut;
				}
				break;

			default:
				break;
		}
	}
	else if( lParams.getSize() == 2 )
	{
		Bu::RegEx re( lParams.first().getString() );
		Bu::FString sPat = lParams.last().getString();
		switch( input.getType() )
		{
			case Variable::typeString:
				if( re.execute( input.getString() ) )
				{
					return replace( re, input.getString(), sPat );
				}
				else
				{
					return input;
				}
				break;

			case Variable::typeList:
				{
					Variable vOut( Variable::typeList );
					for( VarList::iterator i = input.begin(); i; i++ )
					{
						if( re.execute( (*i).toString() ) )
							vOut.append( replace( re, (*i).toString(), sPat ) );
						else
							vOut.append( *i );
					}
					return vOut;
				}
				break;

			default:
				break;
		}
	}
	throw Bu::ExceptionBase(
		"regex does not work on non-string or non-list types.");
}

Bu::FString FunctionRegEx::replace( Bu::RegEx &re, const Bu::FString &sSrc,
		const Bu::FString &sPat )
{
	Bu::FString sOut;

	int iStart, iEnd;
	re.getSubStringRange( 0, iStart, iEnd ); // Get the range of the full match
	
	if( iStart > 0 )
		sOut.append( sSrc, 0, iStart ); 

	for( Bu::FString::const_iterator i = sPat.begin(); i; i++ )
	{
		if( *i == '\\' )
		{
			i++;
			if( *i <= '9' && *i >= '0' )
			{
				int iInd = *i-'0';
				if( iInd < re.getNumSubStrings() )
					sOut += re.getSubString( iInd );
			}
			else
			{
				sOut += *i;
			}
		}
		else
		{
			sOut += *i;
		}
	}

	if( iEnd < sSrc.getSize() )
	{
		sOut.append( sSrc, iEnd, -1 );
	}

	return sOut;
}