0

を使用するワイルドカード式を変更し、それを正規表現に変換して、いくつかの文字列と一致するかどうかを確認することは可能でしょう*?

言い換えると、フィルター(大文字と小文字を区別しない)を使用する場合:*bl?e*これらの文字列に対して:

["Blue", "Black", "Red", "Light blue", "Light black"]

私は手に入れたい:

["Blue, "Light blue"].

正規表現でそれを行う方法を知っている人はいますか?正規表現を使用する以外に、それを行うためのより良い方法はありますか?

私の考えをより明確にするために追加されました...

Ok!...いつものように、私は非常に明確な質問をし、その答えによって私が自分の質問を完全に台無しにしていることに気づいたと思いました。dos('*''?')と同じルールの式(関数のパラメーターとして)に従ってコレクションをフィルター処理する関数を実行したいと思います。正規表現を使うのはいい考えだと思いました。私は正しいですか、正規表現は何ですか?また...私はC#を使用していますが、直接仕事をするものにアクセスできないのではないかと思います。

また、(かなり良い答え)ac#regexステートメントでワイルドカード(任意の文字)を指定するにはどうすればよいですか?

私はついに.netPatternsandPracticesライブラリのGlobクラスを使用しました。

しかし、参考として、これはGlobexpをRegExに変換するための私のコードです。

using System.Text;
using System.Text.RegularExpressions;

namespace HQ.Util.General
{
    public class RegexUtil
    {
        public const string RegExMetaChars = @"*?(){}[]+-^$.|\"; // Do not change the order. Algo depends on it (2 first chars should be dos like wildcard char)

        // ******************************************************************
        /// <summary>
        /// Convert an filter expression with '*' (wildcard any char) and '?' (wildcard on char) into a valid regex and
        /// strip any special regex character
        /// </summary>
        /// <param name="dosLikeExpressionFilter"></param>
        /// <returns></returns>
        public static string DosLikeExpressionFilterToRegExFilterExpression(string dosLikeExpressionFilter)
        {
            StringBuilder regex = new StringBuilder();
            regex.Append("(?i)"); // Case insensitive

            int startIndex = 0;
            int count = dosLikeExpressionFilter.Length;
            while (startIndex < count)
            {
                int metaIndex = RegExMetaChars.IndexOf(dosLikeExpressionFilter[startIndex]);
                if (metaIndex >= 0)
                {
                    if (metaIndex == 0)
                    {
                        regex.Append(".*");
                    }
                    else if (metaIndex == 1)
                    {
                        regex.Append(".");
                    }
                    else
                    {
                        regex.Append("\\");
                        regex.Append(dosLikeExpressionFilter[startIndex]);
                    }
                }
                else
                {
                    regex.Append(dosLikeExpressionFilter[startIndex]);
                }
                startIndex++;
            }

            return regex.ToString();
        }

        // ******************************************************************
        /// <summary>
        /// See 'DosLikeExpressionFilterToRegExFilterExpression' description to see what type of Regex is returned
        /// </summary>
        /// <param name="dosLikeExpressionFilter"></param>
        /// <returns></returns>
        public static Regex DosLikeExpressionFilterToRegEx(string dosLikeExpressionFilter)
        {
            return new Regex(DosLikeExpressionFilterToRegExFilterExpression(dosLikeExpressionFilter));
        }

        // ******************************************************************
    }
}
4

4 に答える 4

2
               Any single character    Any number of characters   Character range
Glob syntax            ?                           *                    [0-9]
Regex syntax           .                           .*                   [0-9]

したがってBl?e、(glob)はBl.e(regex)になり、。に*Bl?e*なり.*Bl.e.*ます。

Joeyが正しく指摘したように、(通常、正規表現エンジンによっては)正規表現の前に付加(?i)して大文字と小文字を区別しないようにすることができます。

ただし、グロブパターンで特別な意味を持たない文字の多くは正規表現で特別な意味を持っているため、グロブから正規表現への単純な検索と置換を行うことはできないことに注意してください。

于 2012-05-11T20:21:12.300 に答える
1

同じ問題 (ユーザー入力から * および ? ワイルドカード パターンを使用して任意の文字列のリストをフィルター処理する) を解決する必要がありましたが、検索対象の星や疑問符をエスケープする拡張機能も必要でした。

SQL の LIKE 演算子 (これらのワイルドカードは % と _ です) は通常、エスケープのためにバックスラッシュを提供するため、私は同じアプローチを取りました。これは、Regex.Escape() を使用し、* を .* および ? に置き換えるという通常は単純な戦略を複雑にします。と 。正規表現を使用するため(問題に対する他の多くの回答を参照)。

いくつかのワイルドカード パターンの正規表現を提供するメソッドは、次のコードでスケッチされています。C# 文字列の拡張メソッドとして実装されています。Doc タグとコメントは、コードを完全に説明する必要があります。

using System.Text.RegularExpressions;

public static class MyStringExtensions
{
    /// <summary>Interpret this string as wildcard pattern and create a corresponding regular expression. 
    /// Rules for simple wildcard matching are:
    /// * Matches any character zero or more times.
    /// ? Matches any character exactly one time.
    /// \ Backslash can be used to escape above wildcards (and itself) for an explicit match,
    /// e.g. \* would then match a single star, \? matches a question mark and \\ matches a backslash.
    /// If \ is not followed by star, question mark or backslash it also matches a single backslash.
    /// Character set matching (by use of rectangular braces []) is NOT used and regarded in this implementation.
    /// </summary>
    /// <param name="wildPat">This string to be used as wildcard match pattern.</param>
    /// <param name="caseSens">Optional parameter for case sensitive matching - default is case insensitive.</param>
    /// <returns>New instance of a regular expression performing the requested matches.
    /// If input string is null or empty, null is returned.</returns>
    public static Regex CreateWildcardRegEx(this string wildPat, bool caseSens = false)
    {
        if (string.IsNullOrEmpty(wildPat))
           return null;

        // 1. STEP: Escape all special characters used in Regex later to avoid unwanted behavior.
        // Regex.Escape() prepends a backslash to any of following characters: \*+?|{[()^$.# and white space 
        wildPat = Regex.Escape(wildPat);

        // 2. STEP: Replace all three possible occuring escape sequences defined for our 
        // wildcard pattern with temporary sub strings that CANNOT exist after 1. STEP anymore.
        // Prepare some constant strings used below - @ in C# makes literal strings really literal - a backslash needs not be repeated!
        const string esc    = @"\\";    // Matches a backslash in a Regex
        const string any    = @"\*";    // Matches a star in a Regex
        const string sgl    = @"\?";    // Matches a question mark in a Regex
        const string tmpEsc = @"||\";   // Instead of doubled | any character Regex.Escape() escapes would do (except \ itself!)
        const string tmpAny =  "||*";   // See comment above
        const string tmpSgl =  "||?";   // See comment above

        // Watch that string.Replace() in C# will NOT stop replacing after the first match but continues instead...
        wildPat = wildPat.Replace(Regex.Escape(esc), tmpEsc)
                         .Replace(Regex.Escape(any), tmpAny)
                         .Replace(Regex.Escape(sgl), tmpSgl);

        // 3. STEP: Substitute our (in 1. STEP escaped) simple wildcards with the Regex counterparts.
        const string regAny = ".*";             // Matches any character zero or more times in a Regex
        wildPat = wildPat.Replace(any, regAny)
                         .Replace(sgl, ".");    // . matches any character in a Regex

        // 4. STEP: Revert the temporary replacements of 2. STEP (in reverse order) and replace with what a Regex really needs to match
        wildPat = wildPat.Replace(tmpSgl, sgl)
                         .Replace(tmpAny, any)
                         .Replace(tmpEsc, esc);

        // 5. STEP: (Optional, for performance) - Simplify multiply occuring * wildcards (cases of ******* or similar)
        // Replace with the regAny string - Use a single Regex.Replace() instead of string.Contains() with string.Replace() in a while loop 
        wildPat = Regex.Replace(wildPat, @"(\.\*){2,}", regAny);

        // 6. STEP: Finalize the Regex with begin and end line tags
        return new Regex('^' + wildPat + '$', caseSens ? RegexOptions.None : RegexOptions.IgnoreCase);

        // 2. and 4. STEP would be obsolete if we don't wanted to have the ability to escape * and ? characters for search
    }
}
于 2021-05-14T12:52:41.417 に答える
0

この正規表現を試してください:

^([\w,\s]*bl\we[\w,\s]*) 

基本的に、「bl」で始まり「e」で終わり、その間に 1 文字の単語を含む単語とスペースのセットを認識します。または

^([\w,\s]*bl(\w+)e[\w,\s]*)

「bl」で始まり「e」で終わる単語を認識したい場合。

もう 1 つの方法は、文字列に対して不正確なマッチング アルゴリズムを使用することです。これがまさにあなたが探しているものかどうかはわかりません。

于 2012-05-11T20:27:03.640 に答える