需要使用正则表达式对字符串执行通配符(*、?等)搜索
我需要对字符串执行通配符(*
、?
等)搜索。 这就是我所做的:
string input = "Message";
string pattern = "d*";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(input))
{
MessageBox.Show("Found");
}
else
{
MessageBox.Show("Not Found");
}
使用上面的代码,“找到”块被击中,但实际上它不应该被击中!
如果我的模式是“e*”,那么只有“Found”应该命中。
我的理解或要求是 d* 搜索应该找到包含“d”后跟任何字符的文本。
我应该将模式更改为“d.*”和“e.*”吗? .NET 中是否有对通配符的支持,它在使用 Regex 类时在内部执行此操作?
I need to perform Wildcard (*
, ?
, etc.) search on a string.
This is what I have done:
string input = "Message";
string pattern = "d*";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(input))
{
MessageBox.Show("Found");
}
else
{
MessageBox.Show("Not Found");
}
With the above code "Found" block is hitting but actually it should not!
If my pattern is "e*" then only "Found" should hit.
My understanding or requirement is d* search should find the text containing "d" followed by any characters.
Should I change my pattern as "d.*" and "e.*"? Is there any support in .NET for Wild Card which internally does it while using Regex class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
来自 http://www.codeproject.com/KB/recipes/wildcardtoregex.aspx:
所以类似
foo*.xls?
的内容将被转换为^foo.*\.xls.$
。From http://www.codeproject.com/KB/recipes/wildcardtoregex.aspx:
So something like
foo*.xls?
will get transformed to^foo.*\.xls.$
.您可以使用名为 LikeString 的 Visual Basic 函数在没有 RegEx 的情况下执行简单的通配符映射。
如果您使用CompareMethod.Text,它将比较不区分大小写。对于区分大小写的比较,您可以使用CompareMethod.Binary。
更多信息请参见:http://www.henrikbrinch.dk /Blog/2012/02/14/Wildcard-matching-in-C
MSDN:http://msdn .microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.likestring%28v=vs.100%29.ASPX
You can do a simple wildcard mach without RegEx using a Visual Basic function called LikeString.
If you use
CompareMethod.Text
it will compare case-insensitive. For case-sensitive comparison, you can useCompareMethod.Binary
.More info here: http://www.henrikbrinch.dk/Blog/2012/02/14/Wildcard-matching-in-C
MSDN: http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.likestring%28v=vs.100%29.ASPX
glob 表达式
d*
的正确正则表达式公式是^d
,这意味着匹配以d
开头的任何内容。(在这种情况下,
@
引用不是必需的,但这是一个很好的做法,因为许多正则表达式使用需要单独保留的反斜杠转义符,并且它还向读者表明该字符串是特殊的)。The correct regular expression formulation of the glob expression
d*
is^d
, which means match anything that starts withd
.(The
@
quoting is not necessary in this case, but good practice since many regexes use backslash escapes that need to be left alone, and it also indicates to the reader that this string is special).Windows 和 *nux 对待通配符的方式不同。
*
、?
和.
由 Windows 以非常复杂的方式处理,一个人的存在或位置会改变另一个人的含义。虽然 *nux 保持简单,但它所做的只是一种简单的模式匹配。除此之外,Windows 匹配?
0 或 1 个字符,Linux 正好匹配 1 个字符。我没有找到这方面的权威文档,这里只是我根据在 Windows 8/XP 上几天的测试得出的结论(命令行,具体是
dir
命令,以及Directory.txt)。 GetFiles
方法也使用相同的规则)和 Ubuntu Server 12.04.1(ls
命令)。我完成了数十个常见和不常见的案例,尽管也有很多失败的案例。Gabe 的回答与 *nux 类似。如果你也想要一个 Windows 风格的,并且愿意接受不完美,那么这里是:
有一件有趣的事情,甚至是 Windows API PathMatchSpec 与 FindFirstFile。试试
a1*.
,FindFirstFile
说它匹配a1
,PathMatchSpec
说不匹配。Windows and *nux treat wildcards differently.
*
,?
and.
are processed in a very complex way by Windows, one's presence or position would change another's meaning. While *nux keeps it simple, all it does is just one simple pattern match. Besides that, Windows matches?
for 0 or 1 chars, Linux matches it for exactly 1 chars.I didn't find authoritative documents on this matter, here is just my conclusion based on days of tests on Windows 8/XP (command line,
dir
command to be specific, and theDirectory.GetFiles
method uses the same rules too) and Ubuntu Server 12.04.1 (ls
command). I made tens of common and uncommon cases work, although there'are many failed cases too.The answer by Gabe works like *nux. If you also want a Windows style one, and are willing to accept the imperfection, then here it is:
There's a funny thing, even the Windows API PathMatchSpec does not agree with FindFirstFile. Just try
a1*.
,FindFirstFile
says it matchesa1
,PathMatchSpec
says not.d*
表示它应该匹配零个或多个“d
”字符。所以任何字符串都是有效的匹配。尝试使用d+
来代替!为了支持通配符模式,我将用 RegEx 等效项替换通配符。就像
*
变成.*
和?
变成.?
。那么上面的表达式就变成了d.*
d*
means that it should match zero or more "d
" characters. So any string is a valid match. Tryd+
instead!In order to have support for wildcard patterns I would replace the wildcards with the RegEx equivalents. Like
*
becomes.*
and?
becomes.?
. Then your expression above becomesd.*
您需要将通配符表达式转换为正则表达式。例如:
You need to convert your wildcard expression to a regular expression. For example:
您必须转义输入通配符模式中的特殊正则表达式符号(例如模式
*.txt
将相当于^.*\.txt$
)因此斜杠、大括号和许多特殊符号必须替换为
@"\" + s
,其中s
- 特殊正则表达式符号。You must escape special Regex symbols in input wildcard pattern (for example pattern
*.txt
will equivalent to^.*\.txt$
)So slashes, braces and many special symbols must be replaced with
@"\" + s
, wheres
- special Regex symbol.您可能需要使用 来自
System.Management.Automation
程序集的WildcardPattern
。请参阅我的回答此处。You may want to use
WildcardPattern
fromSystem.Management.Automation
assembly. See my answer here.我认为@Dmitri 有很好的解决方案
使用通配符匹配字符串 https://stackoverflow.com/a/30300521/1726296
基于他的解决方案,我创建了两个扩展方法。 (归功于他)
可能会有帮助。
用法:
或
I think @Dmitri has nice solution at
Matching strings with wildcard https://stackoverflow.com/a/30300521/1726296
Based on his solution, I have created two extension methods. (credit goes to him)
May be helpful.
Usage:
or
所有上面的代码到最后都不正确。
这是因为当搜索 zz*foo* 或 zz* 时,您将不会得到正确的结果。
如果你在TotalCommander中搜索“abcd”中的“abcd*”,他会找到一个abcd文件,所以所有上面的代码都是错误的。
这是正确的代码。
All upper code is not correct to the end.
This is because when searching zz*foo* or zz* you will not get correct results.
And if you search "abcd*" in "abcd" in TotalCommander will he find a abcd file so all upper code is wrong.
Here is the correct code.
最受接受的答案在大多数情况下都可以正常工作,并且可以在大多数情况下使用:
但是,如果您允许在输入通配符模式中转义,例如“
find \*
”,这意味着您要搜索字符串“find *
”带星号,它不起作用。已经转义的*将转义为“\\\\\\*
”,替换后我们有“^value\\ with\\\\.*$
” ,这是错误的。以下代码(肯定可以优化和重写)处理这种特殊情况:
此处提出了仅使用正则表达式替换的问题解决方案 https ://stackoverflow.com/a/15275806/1105564
The most accepted answer works fine for most cases and can be used in most scenarios:
However if you allow escaping in you input wildcard pattern, e.g. "
find \*
", meaning you want to search for a string "find *
" with asterisk, it won't work. The already escaped * will be escaped to "\\\\\\*
" and after replacing we have "^value\\ with\\\\.*$
", which is wrong.The following code (which for sure can be optimized and rewritten) handles that special case:
Solution for the problem just with Regex substitutions is proposed here https://stackoverflow.com/a/15275806/1105564