⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deelx.h

📁 看看吧C加加环境下的正则表达式引擎deelx
💻 H
📖 第 1 页 / 共 5 页
字号:
					int red = 0;
					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 2, 2, red);

					delta += red;

					if(red > 0)
						nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
					else
						nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);

				break;
				}

			case RCHART('u'):
				if(m_pattern[m_nNextPos+2] != '{')
				{
					int red = 0;
					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 2, 4, red);

					delta += red;

					if(red > 0)
						nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
					else
						nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
				}
				else
				{
					int red = 0;
					unsigned int ch2 = Hex2Int(m_pattern.GetBuffer() + m_nNextPos + 3, sizeof(int) * 2, red);

					delta += red;

					while(m_nNextPos + delta < m_pattern.GetSize() && m_pattern.At(m_nNextPos + delta) != RCHART('}'))
						delta ++;

					delta ++; // skip '}'

					nex2 = CHART_INFO(RCHART(ch2), 0, m_nNextPos, delta);
				}
				break;

			case RCHART('a'): nex2 = CHART_INFO(RCHART('\a'), 0, m_nNextPos, delta); break;
			case RCHART('f'): nex2 = CHART_INFO(RCHART('\f'), 0, m_nNextPos, delta); break;
			case RCHART('n'): nex2 = CHART_INFO(RCHART('\n'), 0, m_nNextPos, delta); break;
			case RCHART('r'): nex2 = CHART_INFO(RCHART('\r'), 0, m_nNextPos, delta); break;
			case RCHART('t'): nex2 = CHART_INFO(RCHART('\t'), 0, m_nNextPos, delta); break;
			case RCHART('v'): nex2 = CHART_INFO(RCHART('\v'), 0, m_nNextPos, delta); break;
			case RCHART('e'): nex2 = CHART_INFO(RCHART( 27 ), 0, m_nNextPos, delta); break;

			case RCHART('G'):  // skip '\G'
				if(m_nCharsetDepth > 0)
				{
					m_nNextPos += 2;
					return 0;
				}
				else
				{
					nex2 = CHART_INFO(ch1, 1, m_nNextPos, delta);
					break;
				}

			case RCHART('L'):
				if( ! m_quote_fun ) m_quote_fun = ::tolower;

			case RCHART('U'):
				if( ! m_quote_fun ) m_quote_fun = ::toupper;

			case RCHART('Q'):
				{
					m_bQuoted   = 1;
					m_nNextPos += 2;
					return 0;
				}

			case RCHART('E'):
				{
					m_quote_fun = 0;
					m_bQuoted   = 0;
					m_nNextPos += 2;
					return 0;
				}

			case 0:
				if(m_nNextPos+1 >= m_pattern.GetSize())
				{
					delta = 1;
					nex2 = CHART_INFO(ch , 0, m_nNextPos, delta);
				}
				else
					nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta); // common '\0' char
				break;

			default:
				nex2 = CHART_INFO(ch1, 0, m_nNextPos, delta);
				break;
			}
		}
		break;

	case RCHART('*'):
	case RCHART('+'):
	case RCHART('?'):
	case RCHART('.'):
	case RCHART('{'):
	case RCHART('}'):
	case RCHART(')'):
	case RCHART('|'):
	case RCHART('$'):
		if(m_nCharsetDepth > 0)
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		else
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		break;

	case RCHART('-'):
		if(m_nCharsetDepth > 0)
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		else
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		break;

	case RCHART('('):
		{
			CHART ch1 = m_pattern[m_nNextPos+1];
			CHART ch2 = m_pattern[m_nNextPos+2];

			// skip remark
			if(ch1 == RCHART('?') && ch2 == RCHART('#'))
			{
				m_nNextPos += 2;
				while(m_nNextPos < m_pattern.GetSize())
				{
					if(m_pattern[m_nNextPos] == RCHART(')'))
						break;

					m_nNextPos ++;
				}

				if(m_pattern[m_nNextPos] == RCHART(')'))
				{
					m_nNextPos ++;

					// get next nex2
					return 0;
				}
			}
			else
			{
				if(m_nCharsetDepth > 0)
					nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
				else
					nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
			}
		}
		break;

	case RCHART('#'):
		if(m_nFlags & EXTENDED)
		{
			// skip remark
			m_nNextPos ++;

			while(m_nNextPos < m_pattern.GetSize())
			{
				if(m_pattern[m_nNextPos] == RCHART('\n') || m_pattern[m_nNextPos] == RCHART('\r'))
					break;

				m_nNextPos ++;
			}

			// get next nex2
			return 0;
		}
		else
		{
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		}
		break;

	case RCHART(' '):
	case RCHART('\f'):
	case RCHART('\n'):
	case RCHART('\r'):
	case RCHART('\t'):
	case RCHART('\v'):
		if(m_nFlags & EXTENDED)
		{
			m_nNextPos ++;

			// get next nex2
			return 0;
		}
		else
		{
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		}
		break;

	case RCHART('['):
		m_nCharsetDepth ++;
		nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		break;

	case RCHART(']'):
		if(m_nCharsetDepth > 0)
		{
			m_nCharsetDepth --;
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		}
		else
		{
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		}
		break;

	case RCHART(':'):
		if(next == CHART_INFO(RCHART('['), 1))
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		else
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		break;

	case RCHART('^'):
		if(m_nCharsetDepth == 0 || next == CHART_INFO(RCHART('['), 1) || (curr == CHART_INFO(RCHART('['), 1) && next == CHART_INFO(RCHART(':'), 1)))
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta);
		else
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		break;

	case 0:
		if(m_nNextPos >= m_pattern.GetSize())
			nex2 = CHART_INFO(ch, 1, m_nNextPos, delta); // end of string
		else
			nex2 = CHART_INFO(ch, 0, m_nNextPos, delta); // common '\0' char
		break;

	default:
		nex2 = CHART_INFO(ch, 0, m_nNextPos, delta);
		break;
	}

	m_nNextPos += delta;

	return 1;
}

template <class CHART> ElxInterface * CBuilderT <CHART> :: GetStockElx(int nStockId)
{
	ElxInterface ** pStockElxs = m_pStockElxs;

	// check
	if(nStockId < 0 || nStockId >= STOCKELX_COUNT)
		return GetStockElx(0);

	// create if no
	if(pStockElxs[nStockId] == 0)
	{
		switch(nStockId)
		{
		case STOCKELX_EMPTY:
			pStockElxs[nStockId] = Keep(new CEmptyElx());
			break;

		case STOCKELX_WORD:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));

				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
				pRange->m_chars .Push(RCHART('_'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_WORD_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));

				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
				pRange->m_chars .Push(RCHART('_'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DOT_ALL:
			pStockElxs[nStockId] = Keep(new CRangeElxT <CHART> (0, 0));
			break;

		case STOCKELX_DOT_NOT_ALL:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));

				pRange->m_chars .Push(RCHART('\n'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_SPACE:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));

				pRange->m_chars .Push(RCHART(' '));
				pRange->m_chars .Push(RCHART('\t'));
				pRange->m_chars .Push(RCHART('\r'));
				pRange->m_chars .Push(RCHART('\n'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_SPACE_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));

				pRange->m_chars .Push(RCHART(' '));
				pRange->m_chars .Push(RCHART('\t'));
				pRange->m_chars .Push(RCHART('\r'));
				pRange->m_chars .Push(RCHART('\n'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DIGITAL:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 1));

				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DIGITAL_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (0, 0));

				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_WORD_RIGHTLEFT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));

				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
				pRange->m_chars .Push(RCHART('_'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_WORD_RIGHTLEFT_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));

				pRange->m_ranges.Push(RCHART('A')); pRange->m_ranges.Push(RCHART('Z'));
				pRange->m_ranges.Push(RCHART('a')); pRange->m_ranges.Push(RCHART('z'));
				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));
				pRange->m_chars .Push(RCHART('_'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DOT_ALL_RIGHTLEFT:
			pStockElxs[nStockId] = Keep(new CRangeElxT <CHART> (1, 0));
			break;

		case STOCKELX_DOT_NOT_ALL_RIGHTLEFT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));

				pRange->m_chars .Push(RCHART('\n'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_SPACE_RIGHTLEFT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));

				pRange->m_chars .Push(RCHART(' '));
				pRange->m_chars .Push(RCHART('\t'));
				pRange->m_chars .Push(RCHART('\r'));
				pRange->m_chars .Push(RCHART('\n'));
				pRange->m_chars .Push(RCHART('\f'));
				pRange->m_chars .Push(RCHART('\v'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_SPACE_RIGHTLEFT_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));

				pRange->m_chars .Push(RCHART(' '));
				pRange->m_chars .Push(RCHART('\t'));
				pRange->m_chars .Push(RCHART('\r'));
				pRange->m_chars .Push(RCHART('\n'));
				pRange->m_chars .Push(RCHART('\f'));
				pRange->m_chars .Push(RCHART('\v'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DIGITAL_RIGHTLEFT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 1));

				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));

				pStockElxs[nStockId] = pRange;
			}
			break;

		case STOCKELX_DIGITAL_RIGHTLEFT_NOT:
			{
				CRangeElxT <CHART> * pRange = (CRangeElxT <CHART> *)Keep(new CRangeElxT <CHART> (1, 0));

				pRange->m_ranges.Push(RCHART('0')); pRange->m_ranges.Push(RCHART('9'));

				pStockElxs[nStockId] = pRange;
			}
			break;
		}
	}

	// return
	return pStockElxs[nStockId];
}

template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildAlternative(int vaflags)
{
	if(curr == CHART_INFO(0, 1))
		return GetStockElx(STOCKELX_EMPTY);

	// flag instance
	int flags = vaflags;

	// first part
	ElxInterface * pAlternativeOne = BuildList(flags);

	// check alternative
	if(curr == CHART_INFO(RCHART('|'), 1))
	{
		CAlternativeElx * pAlternative = (CAlternativeElx *)Keep(new CAlternativeElx());
		pAlternative->m_elxlist.Push(pAlternativeOne);

		// loop
		while(curr == CHART_INFO(RCHART('|'), 1))
		{
			// skip '|' itself
			MoveNext();

			pAlternativeOne = BuildList(flags);
			pAlternative->m_elxlist.Push(pAlternativeOne);
		}

		return pAlternative;
	}

	return pAlternativeOne;
}

template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildList(int & flags)
{
	if(curr == CHART_INFO(0, 1) || curr == CHART_INFO(RCHART('|'), 1) || curr == CHART_INFO(RCHART(')'), 1))
		return GetStockElx(STOCKELX_EMPTY);

	// first
	ElxInterface * pListOne = BuildRepeat(flags);

	if(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('|'), 1) && curr != CHART_INFO(RCHART(')'), 1))
	{
		CListElx * pList = (CListElx *)Keep(new CListElx(flags & RIGHTTOLEFT));
		pList->m_elxlist.Push(pListOne);

		while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('|'), 1) && curr != CHART_INFO(RCHART(')'), 1))
		{
			pListOne = BuildRepeat(flags);

			// add
			pList->m_elxlist.Push(pListOne);
		}

		return pList;
	}

	return pListOne;
}

template <class CHART> ElxInterface * CBuilderT <CHART> :: BuildRepeat(int & flags)
{
	// simple
	ElxInterface * pSimple = BuildSimple(flags);

	if(curr.type == 0) return pSimple;

	// is quantifier or not
	int bIsQuantifier = 1;

	// quantifier range
	unsigned int nMin = 0, nMax = 0;

	switch(curr.ch)
	{
	case RCHART('{'):
		{
			CBufferT <char> re;

			// skip '{'
			MoveNext();

			// copy
			while(curr != CHART_INFO(0, 1) && curr != CHART_INFO(RCHART('}'), 1))
			{
				re.Append(((curr.ch & (CHART)0xff) == curr.ch) ? (char)curr.ch : 0, 1);
				MoveNext();
			}

			// skip '}'
			MoveNext();

			// read
			int red;
			char * str = re.GetBuffer();

			if( ! ReadDec(str, nMin) )
				red = 0;
			else if( *str != ',' )
				red = 1;
			else
			{
				str ++;

				if( ! ReadDec(str, nMax) )
					red = 2;
				else
					red = 3;
			}

			// check
			if(red  <=  1 ) nMax = nMin;
			if(red  ==  2 ) nMax = INT_MAX;
			if(nMax < nMin) nMax = nMin;
		}
		break;

	case RCHART('?'):
		nMin = 0;
		nMax = 1;

		// skip '?'
		MoveNext();
		break;

	case RCHART('*'):
		nMin = 0;
		nMax = INT_MAX;

		// skip '*'
		MoveNext();
		break;

	case RCHART('+'):
		nMin = 1;
		nMax = INT_MAX;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -