有没有 VB。C#中的类似NET的运算符?

Is there a VB.NET-Like operator in C#?

提问人:Robert 提问时间:7/18/2014 最后编辑:Tim SchmelterRobert 更新时间:11/17/2023 访问量:7760

问:

我正在重写一个 vb.net 应用程序,我不能声称对 vb 很擅长。我需要在 C# 中编写这个等效项:

Dim bigList = (From gme In dtx.gmc_message_elements 
              Where gme.element_key_name Like "*email" _
              Or gme.element_key_name Like "*web" 
              Or gme.element_key_name Like "*both" _
              Select gme.element_key_name Distinct).ToList()

到目前为止,我有:

var bigList = (from gme in dtx.gmc_message_elements 
               where gme.element_key_name Like "*email" 
               || gme.element_key_name Like "*web" 
               || gme.element_key_name Like "*both" 
               select gme.element_key_name).FirstOrDefault().ToList();

正如你所看到的,我不确定 like 运算符的等价物是什么。我通过几个代码转换器运行了它,它们不断抛出错误。

C# vb.net LINQ

评论

0赞 Jeroen Vannevel 7/18/2014
您查询的来源是什么? 可能是合适的。.Where(x => x.EndsWith("email");
0赞 Tim Schmelter 7/18/2014
C# 中没有运算符,在这种情况下,您可以使用 (如果是 ),否则您需要使用正则表达式或 ( 如果是 )。LikeString.EndsWithLinq-To-ObjectsSqlMethods.LikeLinq-To-Sql
0赞 Lukazoid 7/18/2014
这个问题不是重复的,这涉及将 VB.NET 运算符转换为 C# 等效运算符,而另一个问题是 SQL 运算符,不同的事情......LikeLIKE
0赞 Jeroen Vannevel 7/18/2014
@Robert:它位于您帖子的顶部(也许您需要刷新)
1赞 Holf 7/18/2014
在 C# 中可以实现相同的效果,但您没有得到相同的语法糖,因此它有点难看:它在命名空间中。更多信息在这里: msdn.microsoft.com/en-us/library/...where LikeOperator.LikeString(mySourceString, "*Something*", CompareMethod.Text)Microsoft.VisualBasic.CompilerServices

答:

5赞 Amir Popovich 7/18/2014 #1

根据需要使用 StartsWith 或 EndsWithContains 静态方法。string

评论

2赞 Carl Onager 1/21/2019
这些方法不允许像 Like 那样使用通配符
0赞 juharr 4/2/2019
此外,这些方法不是静态方法。
22赞 Lukazoid 7/18/2014 #2

若要获得最等效的功能,请确保 C# 项目具有对 Microsoft.VisualBasic 程序集的引用。

然后,您可以直接从 C# 中使用 VB.NET 运算符,例如Like

LikeOperator.LikeString(gme.element_key_name, "*web", CompareMethod.Text);

请务必包括

using Microsoft.VisualBasic.CompilerServices;

这将获得最等效的功能,但我认为这有点黑客攻击。

其他选项是使用 String.StartsWith、String.EndsWithString.Contains正则表达式

0赞 ketan Shah 1/28/2016 #3

我认为正则表达式是最好的选择。由于 Like 操作支持 *,?, # 和 [], 我认为可能存在复杂的模式,可以使用正则表达式库轻松匹配。例如。以下行将返回 true。

"aBBBa" Like "a*a" "ajhfgZ1" Like "*Z[12]"

现在这取决于您的应用程序。如果您只是使用它来匹配简单的硬编码字符串,则可以直接使用 String.Contains、String、StartsWith 或 String.EndsWith,但对于复杂的匹配,请使用正则表达式以获得最佳结果。

评论

1赞 31eee384 1/28/2016
您可能应该添加您建议的实际正则表达式。如果你想说是一个正则表达式,那是错误的。 也不匹配 -- 它只匹配 0 或更多 s,然后再匹配另一个。你的意思可能是 和 .(或者你可能只是试图演示 Like 语法,但这对我来说并不清楚。*Z[12]a*aaBBBaaaa.*aZ[12]
0赞 ketan Shah 1/29/2016
hiii a*a 确实与 aBBBa 匹配。并且 “Like” 操作将模式与字符串匹配,因此等式的模式部分确实支持 * , ?等等,*Z[12] 可以转换为正则表达式,我的意思是,但对于 LIKE 操作,这是可以使用的方式。更多信息在 msdn.microsoft.com/en-us/library/swf8kaxw.aspx 无论如何,如果我错了,请随时纠正我。这就是我学习:)
2赞 31eee384 1/29/2016
好吧,我的抱怨实际上只是不清楚你的例子是什么意思。 让我相信接下来的几行将有正则表达式。指出你举例子只是为了表明 Like 很复杂,我认为会澄清它。which can be matched easily using the Regex library. For eg. the following lines will return true.
0赞 Eric Pitz 6/1/2023 #4

正如其他人已经指出的那样,C# 中没有 Like 运算符。

此外,它在 .net 标准的 VB.Net 中不可用。(已为 .net 再次添加)

我的情况是该模式是用户输入。迁移到网络标准,我唯一的选择就是自己实现它。我选择将模式转换为等效的正则表达式:

<Extension()>
Public Function VbLike(str As String, pattern As String) As Boolean
    Dim resultPattern = New Text.StringBuilder
    Dim insideList = False
    Dim prevInsideList = False
    For i = 0 To pattern.Length - 1
        Dim c = pattern(i)
        Dim tempInsideList = insideList

        ' Manage pattern start
        If i = 0 AndAlso c <> "*"c Then
            resultPattern.Append("^"c)
        End If

        ' Manage characterlists
        If c = "["c AndAlso Not insideList Then
            insideList = True
            resultPattern.Append(c)
        ElseIf c = "]"c AndAlso insideList Then
            insideList = False
            resultPattern.Append(c)

            ' Special chars for Like that need to be converted
        ElseIf c = "!"c AndAlso insideList AndAlso Not prevInsideList Then
            resultPattern.Append("^"c)
        ElseIf c = "?"c AndAlso Not insideList Then
            resultPattern.Append("."c)
        ElseIf c = "#"c AndAlso Not insideList Then
            resultPattern.Append("\d")
        ElseIf c = "*"c AndAlso i = 0 Then
            ' Nothing to append
        ElseIf c = "*"c AndAlso i = pattern.Length - 1 Then
            ' Nothing to append
        ElseIf c = "*"c AndAlso Not insideList Then
            resultPattern.Append(".*")

            ' Special chars for Regex that need to be escaped
        ElseIf c = "."c OrElse c = "\"c OrElse c = "("c OrElse c = ")"c Then
            resultPattern.Append("\"c)
            resultPattern.Append(c)
        Else
            resultPattern.Append(c)
        End If

        ' Manage pattern end
        If i = pattern.Length - 1 AndAlso c <> "*"c Then
            resultPattern.Append("$"c)
        End If

        prevInsideList = tempInsideList
    Next

    Return Regex.IsMatch(str, resultPattern.ToString, RegexOptions.Singleline Or RegexOptions.IgnoreCase Or RegexOptions.CultureInvariant)
End Function
0赞 Tom 11/17/2023 #5

这是 Eric Pitz 的 VbLike 代码转换为 C#,因为原始海报试图在 C# 中重新创建此函数。

public bool VbLike(string str, string pattern)
{
    var resultPattern = new System.Text.StringBuilder();
    var insideList = false;
    var prevInsideList = false;
    for (var i = 0; i < pattern.Length; i++)
    {
        var c = pattern[i];
        var tempInsideList = insideList;

        // Manage pattern start
        if (i == 0 && c != '*')
        {
            resultPattern.Append('^');
        }

        // Manage characterlists
        if (c == '[' && !insideList)
        {
            insideList = true;
            resultPattern.Append(c);
        }
        else if (c == ']' && insideList)
        {
            insideList = false;
            resultPattern.Append(c);
        }
        else if (c == '!' && insideList && !prevInsideList)
        {
            // Special chars for Like that need to be converted
            resultPattern.Append('^');
        }
        else if (c == '?' && !insideList)
        {
            resultPattern.Append('.');
        }
        else if (c == '#' && !insideList)
        {
            resultPattern.Append(@"\d");
        }
        else if (c == '*' && i == 0)
        {
            // Nothing to append
        }
        else if (c == '*' && i == pattern.Length - 1)
        {
            // Nothing to append
        }
        else if (c == '*' && !insideList)
        {
            resultPattern.Append(".*");
        }
        else if (c == '.' || c == '\\' || c == '(' || c == ')')
        {
            // Special chars for Regex that need to be escaped
            resultPattern.Append('\\');
            resultPattern.Append(c);
        }
        else
        {
            resultPattern.Append(c);
        }

        // Manage pattern end
        if (i == pattern.Length - 1 && c != '*')
        {
            resultPattern.Append('$');
        }

        prevInsideList = tempInsideList;
    }

    return System.Text.RegularExpressions.Regex.IsMatch(str, resultPattern.ToString(), System.Text.RegularExpressions.RegexOptions.Singleline | System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.CultureInvariant);
}

评论

0赞 Gert Arnold 11/17/2023
不幸的是,这与你提到的答案一样不适用,因为问题显然是关于 LINQ-to-SQL,其中不受支持。Regex.IsMatch