繁体   English   中英

我想使用 Regex.IsMatch 在 VB.net Visual Basic 中查找 TB、GB、MB

[英]i want to use Regex.IsMatch to find TB, GB, MB in VB.net Visual Basic

我有一个文本框,我需要验证以下条目并且还需要替换

“3 GB”有效输入

“3.2 GB”有效输入

“3.2GB”有效输入>>然后替换为“3.2GB

"3.2"无效输入,要求遵循正确MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")

"VGGGB"无效输入,要求遵循正确MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")

Sub Main()
    Dim input = Console.ReadLine().ToUpper()
    Dim nInput, value
    Dim ChkDecimal As Double
    If input IsNot "" Then
        If input.EndsWith("TB") Then
            nInput = input.Replace("TB", "")
            If nInput IsNot vbNullString And IsNumeric(nInput) Then
                value = Convert.ToDouble(nInput)
                value = CDbl(value * 1048576 + 1)
                ChkDecimal = FormatNumber(CDbl(value / 1048576), 2) Mod 1 ' check the number has a valid Decimal value
                If ChkDecimal = 0 Then
                    Console.WriteLine(FormatNumber(CDbl(value / 1048576), 0) & " TB")
                Else
                    Console.WriteLine(FormatNumber(CDbl(value / 1048576), 2) & " TB")
                End If
            Else
                Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
            End If
        ElseIf (input.EndsWith("GB")) Then
            nInput = input.Replace("GB", "")
            If nInput IsNot vbNullString And IsNumeric(nInput) Then
                value = Convert.ToDouble(nInput)
                value = CDbl(value * 1024)
                ChkDecimal = FormatNumber(CDbl(value / 1024), 2) Mod 1 ' check the number has a valid Decimal value
                If ChkDecimal = 0 Then
                    Console.WriteLine(FormatNumber(CDbl(value / 1024), 0) & " GB")
                Else
                    Console.WriteLine(FormatNumber(CDbl(value / 1024), 2) & " GB")
                End If
            Else
                Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
            End If
        ElseIf input.EndsWith("MB") = True Then
            nInput = input.Replace("MB", "")
            If nInput IsNot vbNullString And IsNumeric(nInput) Then
                value = Convert.ToDouble(nInput)
                value = CDbl(value * 1)
                Console.WriteLine(FormatNumber(CDbl(value * 1), 0) & " MB")
            Else
                Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
            End If
        Else
            Console.WriteLine("Invalid format!! should like: 99.99 MB/GB/TB")
        End If
    Else
        Console.WriteLine("Capacity input Format: 99.99 MB/GB/TB")
    End If
End Sub
  • 我不会为此使用正则表达式,因为下面描述了一种更简单(也更健壮)的方法。
  • 如果您确实使用正则表达式,则需要将所有单元名称添加到表达式中,这很痛苦。 正则表达式不太适合接受大量可能的文字输入。
  • 使用正则表达式也意味着输入不会是文化感知的,这对可用性不利(因为世界上许多地方在数字上交换,.字形) - 你真的不想处理类似的事情数字分组等

相反,首先提取并验证单位名称,然后使用Decimal.TryParse解析数值

像这样(使用 C# 因为这里是凌晨 2 点,我没有得到报酬来写这个答案):

void Example()
{
    String textBoxValue = "3 GB";
    if( TryParseBinaryDataQuantity( textBoxValue, out Int64 valueBytes ) )
    {
        MessageBox.Show( "Visual Basic is dead." );
    }
    else
    {
        MessageBox.Show( "Input is not a valid binary data quantity." );
    }
}

public static Boolean TryParseBinaryDataQuantity( String input, out Int64 valueBytes )
{
    input = ( input ?? "" ).Trim();
    if( input.Length < 3 ) // input is too short to be meaningful.
    {
        valueBytes = default;
        return false;
    }

    // Extract the unit-name by taking the last 3 characters of the input string and trimming any whitespace (this isn't the most robust or correct approach, but I'm feeling lazy):
    String unitName = input.Substring( startIndex: input.Length - 3 );

    // Validate the unit-name and get the bytes multiplier:
    if( !TryParseBinaryDataUnit( unitName, out Int64 multiplier ) )
    {
        valueBytes = default;
        return false;
    }

    // Consider repeating the above but for the last 2 characters of the string in order to match input like "3GB" instead of "3GiB" and "3 GB" and "3 GiB".

    // Parse and multiply:
    String numberPart = input.Substring( startIndex: 0, length: input.Length - 3 );
    if( Decimal.TryParse( numberPart, NumberStyles.Any, CultureInfo.CurrentCulture, out Decimal quantity )
    {
        Decimal bytesValue = quantity * multiplier;

        // Fail if the bytesValue is non-integral or negative:
        if( bytesValue != Math.Floor( bytesValue ) || bytesValue < 0 )
        {
            valueBytes = default;
            return false;
        }

        return (Int64)bytesValue;
    }
}

private static Boolean TryParseBinaryDataUnit( String unitName, out Int64 equivalentBytes )
{
    if( "GB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024 * 1024 * 1024; // or 1000 * 1000 * 1000 depending on if you're differentiating between GiB and GB.
        return true;
    }
    else if( "GiB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024 * 1024 * 1024;
        return true;
    }
    else if( "MiB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024 * 1024;
        return true;
    }
    else if( "MB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024 * 1024;
        return true;
    }
    else if( "KB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024;
        return true;
    }
    else if( "KB".Equals( unitName, StringComparison.CurrentCultureCaseInsensitive ) )
    {
        equivalentBytes = 1024;
        return true;
    }
    else
    {
        equivalentBytes = default;
        return false;
    }
}

我会建议您使用适当的库来解析给定的输入。 我过去曾使用过一个( https://github.com/omar/ByteSize

这是如何执行此操作的快速示例。 我知道必须有更好的方法来做到这一点,但这会做的工作=)

var input = Console.ReadLine();
input = input.ToLower();
var reg = Regex.Match(input, "([\\d\\.]+)");
if (reg.Success && double.TryParse(reg.Groups[1].Value, out double rawSize))
{
    if (input.EndsWith("tb"))
        Console.WriteLine(ByteSize.FromTeraBytes(rawSize));
    else if (input.EndsWith("gb"))
        Console.WriteLine(ByteSize.FromGigaBytes(rawSize));
    else if (input.EndsWith("mb"))
        Console.WriteLine(ByteSize.FromMegaBytes(rawSize));
    else if (input.EndsWith("kb"))
        Console.WriteLine(ByteSize.FromKiloBytes(rawSize));
}

输入> 1234.56mb

输出> 1.23 GB

你可以试试我的方法如下:

Imports System.Text.RegularExpressions
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '1.3 GB
        '1.3gb
        '1gb
        Console.WriteLine("Pleasen input your entry:")
        Dim str As String = TextBox1.Text
        Dim str1 As String = str.Substring(str.Length - 2, 2)
        If str1.ToUpper = "TB" Or str1.ToUpper = "GB" Or str1.ToUpper = "MB" Then
            Dim str2 As String = str.Remove(str.Length - 2)
            Dim str3 As String = str.Substring(str2.Length - 1, 1)
            If str3 = " " Then
                Dim str4 As String = str.Remove(str.Length - 3)

                If Regex.IsMatch(str4, "^\d*[.]?\d*$") Then
                    MsgBox("valid input")
                Else
                    MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
                    Return
                End If
            Else
                If Regex.IsMatch(str2, "^\d*[.]?\d*$") Then
                    TextBox1.Text = str.Insert(str.Length - 2, " ")
                    MsgBox("valid input")
                Else
                    MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
                    Return
                End If
            End If
        Else
            MsgBox("follow the format like: 1 TB or 1.1 TB, 1 GB, 10 MB")
            Return
        End If
    End Sub
End Class

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM