我编写用正则表达式解析文本的程序。正则表达式应该从用户处获得。我希望为用户输入使用glob语法,并在内部将glob字符串转换为正则表达式。例如:从glob表达式创建正则表达式
"foo.? bar*"
应转换为
"^.*foo\.\w\bar\w+.*"
不知怎的,我需要从字符串逃避所有有意义的字符,然后我需要更换水珠*和?具有适当的正则表达式语法的字符。最简单的方法是什么?
我编写用正则表达式解析文本的程序。正则表达式应该从用户处获得。我希望为用户输入使用glob语法,并在内部将glob字符串转换为正则表达式。例如:从glob表达式创建正则表达式
"foo.? bar*"
应转换为
"^.*foo\.\w\bar\w+.*"
不知怎的,我需要从字符串逃避所有有意义的字符,然后我需要更换水珠*和?具有适当的正则表达式语法的字符。最简单的方法是什么?
只是发布一个链接作为答案不是一个好的答案。如果链接在未来中断,该怎么办?我们鼓励您在答案中引用链接,这样如果链接中断,答案仍然存在堆栈溢出。 – 2013-07-21 21:29:33
我写我自己的函数,用C++和boost ::正则表达式
std::string glob_to_regex(std::string val)
{
boost::trim(val);
const char* expression = "(\\*)|(\\?)|([[:blank:]])|(\\.|\\+|\\^|\\$|\\[|\\]|\\(|\\)|\\{|\\}|\\\\)";
const char* format = "(?1\\\\w+)(?2\\.)(?3\\\\s*)(?4\\\\$&)";
std::stringstream final;
final << "^.*";
std::ostream_iterator<char, char> oi(final);
boost::regex re;
re.assign(expression);
boost::regex_replace(oi, val.begin(), val.end(), re, format, boost::match_default | boost::format_all);
final << ".*" << std::ends;
return final.str();
}
它看起来像一切工作正常
我不知道我完全了解要求。如果我假设用户想要在他们的搜索匹配中找到文本“条目”,那么我认为这种蛮横的方式将作为一个开始。
首先逃避一切正则表达式的意义。然后使用非正则表达式替换替换(现在已转义)的glob字符并构建正则表达式。像这样在Python:
regexp = re.escape(search_string).replace(r'\?', '.').replace(r'\*', '.*?')
对于问题的搜索字符串,这将构建一个正则表达式,看起来像这样(生):
foo\..\ bar.*?
用于在Python代码片段:
search = "foo.? bar*"
text1 = 'foo bar'
text2 = 'gazonk foo.c bar.m m.bar'
searcher = re.compile(re.escape(s).replace(r'\?', '.').replace(r'\*', '.*?'))
for text in (text1, text2):
if searcher.search(text):
print 'Match: "%s"' % text
产品:
Match: "gazonk foo.c bar.m m.bar"
请注意,如果您检查匹配对象,则可以找到有关匹配的更多信息并用于突出显示或其他内容。
当然,可能还有更多,但它应该是一个开始。
这就对了,但你需要alsough替换()| \ []和其他有意义的字符在字母串 – Lazin 2009-01-15 10:59:29
不需要不完整或不可靠的黑客。这里有一个python包含的函数
>>> import fnmatch
>>> fnmatch.translate('*.foo')
'.*\\.foo$'
>>> fnmatch.translate('[a-z]*.txt')
'[a-z].*\\.txt$'
jPaq的RegExp.fromWildExp函数做了类似这样的事情。从是网站的前面页的示例进行的以下:
// Find a first substring that starts with a capital "C" and ends with a
// lower case "n".
alert("Where in the world is Carmen Sandiego?".findPattern("C*n"));
// Finds two words (first name and last name), flips their order, and places
// a comma between them.
alert("Christopher West".replacePattern("(<*>) (<*>)", "p", "$2, $1"));
// Finds the first number that is at least three numbers long.
alert("2 to the 64th is 18446744073709551616.".findPattern("#{3,}", "ol"));
在R,有包含在基本分布glob2rx
功能:
http://stat.ethz.ch/R-manual/R-devel/library/utils/html/glob2rx.html
正则表达式看起来有点奇怪。像:“^。* foo”可以写成“foo”。我认为这个通用的明星会转化为正则表达式“*?”。搜索空间在哪里?和\ bar匹配以“ar”开头的单词。 – PEZ 2009-01-15 09:17:46