2

私はGSKinnerのRegExrツールを使用して、他の多くのゴミを含むフィールドで認証番号を見つけることができるパターンを考え出すのに役立てています。認証番号は、文字(場合によっては)、数字(常に)、およびハイフン(場合によっては)を含む文字列です(つまり、認証には常にどこかに数字が含まれますが、ハイフンと文字が含まれるとは限りません)。さらに、認証番号は、検索しているフィールドのどこにでも配置できます。

適切な認証番号の例は次のとおりです。

 5555834384734  ' All digits
 12110-AANM     ' Alpha plus digits, plus hyphens
 R-455545-AB-9  ' Alpha plus digits, plus multiple hyphens
 R-45-54A-AB-9  ' Alpha plus digits, plus multiple hyphens
 W892160        ' Alpha plus digits without hypens

これは、追加のガベージを含むサンプルデータです。これは、実際の認証番号にハイフンまたはスペースなしで追加され、番号の一部のように見える場合があります。ただし、ガベージは予測可能な形式/単語(REF、CHEST、IP、AMB、OBV、およびHOLD)で発生しますが、これらは認証番号の一部ではありません。

 5557653700 IP
 R025257413-001
 REF 120407175
 SNK601M71016
 U0504124 AMB
 W892160
 019870270000000
 00Q926K2
 A025229563
 01615217 AMB
 12042-0148
 SNK601M71016
 12096NHP174
 12100-ACDE
 12110-AANM
 12114AD5QIP
 REF-34555
 3681869/OBV ONL

これが私が使用しているパターンです:

 "\b[a-zA-Z]*[\d]+[-]*[\d]*[A-Za-z0-9]*[\b]*"

私はRegExpを学習しているので、間違いなく改善できますが、以下の状況ではなく、上記の場合に機能します。

 REFA5-208-4990IP  'Extract the string 'A5-208-4990'without REF or IP
 OBV1213110379     'Extract the string '1213110379' without the OBV
 5520849900AMB     'Extract the string '5520849900' without AMB
 5520849900CHEST   'Extract the string '5520849900' without CHEST
 5520849900-IP     'Extract the string '5520849900' without -IP
 1205310691-OBV    'Extract the string without the -OBV
 R-025257413-001   'Numbers of this form should also be allowed.
 NO PCT 93660      'If string contains the word NO anywhere, it is not a match
 HOLDA5-208-4990   'If string contains the word HOLD anywhere, it is not a match

誰かが助けることができますか?

テストの目的で、サンプル入力データを含むテーブルを作成するSubを次に示します。

 Sub CreateTestAuth()

 Dim dbs As Database
 Set dbs = CurrentDb

 With dbs
     .Execute "CREATE TABLE tbl_test_auth " _
         & "(AUTHSTR CHAR);"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('5557653700 IP');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "(' R025257413-001');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('REF 120407175');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('SNK601M71016');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('U0504124 AMB');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('3681869/OBV ONL');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('REFA5-208-4990IP');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('5520849900AMB');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('5520849900CHEST');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('5520849900-IP');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('1205310691-OBV');"
     .Execute " INSERT INTO tbl_test_auth " _
         & "(AUTHSTR) VALUES " _
         & "('HOLDA5-208-4990');"
     .Close
 End With
 End Sub
4

5 に答える 5

1

さて、最初は、追加の要件によって正規表現がはるかに長くなると思いました。
しかし、前向きな見方をすれば、実際にはほぼ同じサイズです。今回は正規表現のみ:
\b(?=.*\d)([a-z0-9]+(?:-[a-z0-9]+)*)\b

またはコメントで分解(空白を無視):

\b                     # Word start
  (?=.*\d)             # A number has to follow somewhere after this point
  (                    # Start capture group
    [a-z0-9]+          # At least one alphanum
    (?:-[a-z0-9]+)*    # Possibly more attached with hyphen
  )                    # End capture group
\b                     # Word end

ただし、可変幅の先読みは、すべての正規表現フレーバーでサポートされているわけではないことに注意してください。VBAについてはわかりません。

2番目の注意:(?=)単語の終わりの後に数字が表示されれば、物事も満たされます。したがって、
DONT- RECOGNIZE-MEでは-1-5ay-はい
、太字の部分がキャプチャされます。

于 2012-05-30T20:39:23.927 に答える
0

\bそもそも問題です。また、いくつかのスペースといくつかのダッシュを処理する必要があります。これを試してみてください" [a-zA-Z|\s|-]*[\d]+[-]*[\d]*[A-Za-z0-9]*[\b]*"。これは認証番号でのみ実行してください。

于 2012-05-29T13:08:57.640 に答える
0

その追加のフィルタリングのために、2段階のアプローチを使用します。

var splitter = new Regex(@"[\t\n\r]+", RegexOptions.Multiline);
const string INPUT = @"REFA5-208-4990IP
       OBV1213110379
       5520849900AMB
       5520849900CHEST
       5520849900-IP
       1205310691-OBV
       R-025257413-001
       NO PCT 93660
       HOLDA5-208-4990";
string[] lines = splitter.Split(INPUT);

var blacklist = new[] { "NO", "HOLD" };
var ignores = new[] { "REF", "IP", "CHEST", "AMB", "OBV" };

var filtered = from line in lines
         where blacklist.All(black => line.IndexOf(black) < 0)
         select ignores.Aggregate(line, (acc, remove) => acc.Replace(remove, ""));

var authorization = new Regex(@"\b([a-z0-9]+(?:-[a-z0-9]+)*)\b", RegexOptions.IgnoreCase);
foreach (string s in filtered)
{
  Console.Write("'{0}' ==> ", s);
  var match = authorization.Match(s);
  if (match.Success)
  {
    Console.Write(match.Value);
  }
  Console.WriteLine();
}

プリント:

'A5-208-4990' ==> A5-208-4990
' 1213110379' ==> 1213110379
' 5520849900' ==> 5520849900
' 5520849900' ==> 5520849900
' 5520849900-' ==> 5520849900
' 1205310691-' ==> 1205310691
' R-025257413-001' ==> R-025257413-001
于 2012-05-29T13:28:23.407 に答える
0

場合によっては、何らかの方法で固く固執するよりも、緩めるほうが簡単な場合があります。:)

これを試して:

1-この関数を追加します

Public Function RemoveJunk(ByVal inputValue As String, ParamArray junkWords() As Variant) As String
    Dim junkWord
    For Each junkWord In junkWords
        inputValue = Replace(inputValue, junkWord, "", , , vbBinaryCompare)
    Next
    RemoveJunk = inputValue
End Function

2-これで作業は簡単です。使用方法については、以下の例を参照してください。

Sub Sample()
    Dim theText As String
    theText = " REFA5-208-4990IP blah blah "
    theText = RemoveJunk(theText, "-REF", "REF", "-IP", "IP", "-OBV", "OBV") '<-- complete this in a similar way

    Debug.Print theText

    '' -- now apply the regexp here --


End Sub

RemoveJunk関数呼び出しの完了は少し注意が必要です。短いものの前に長いものを置きます。たとえば、-OBVは「OBV」の前に来る必要があります。

試してみて、問題が解決するかどうかを確認してください。

于 2012-05-29T13:28:30.537 に答える
0

サンプル入力ファイル(このファイルへのパスs / bはとして与えられますfunction<GetMatches>inputFilePath

5557653700 IP
R025257413-001
REF 120407175
SNK601M71016
U0504124 AMB
W892160
019870270000000
00Q926K2
A025229563
01615217 AMB
12042-0148
SNK601M71016
12096NHP174
12100-ACDE
12110-AANM
12114AD5QIP
REF-34555
3681869/OBV ONL

これがファイルに保存されたジャンクです(このファイルへのパスs / bはとして与えられますfunction<GetMatches>replaceDBPath

^REF
IP$
^OBV
AMB$
CHEST$
-OBV$
^.*(NO|HOLD).*$

そして、ここに行きますbas

Option Explicit
'This example uses the following references:
'Microsoft VBScript Regular Expressions 5.5 and Microsoft Scripting Runtime

Private fso As New Scripting.FileSystemObject
Private re As New VBScript_RegExp_55.RegExp

Private Function GetJunkList(fpath$) As String()
0     On Error GoTo errHandler
1     If fso.FileExists(fpath) Then
2         Dim junkList() As String, mts As MatchCollection, mt As Match, pos&, tmp$
3         tmp = fso.OpenTextFile(fpath).ReadAll()
4         With re
5             .Global = True
6             .MultiLine = True
7             .Pattern = "[^\r\n]+"
8             Set mts = .Execute(tmp)
9             ReDim junkList(mts.Count - 1)
10            For Each mt In mts
11                junkList(pos) = mt.Value
12                pos = pos + 1
13            Next mt
14        End With
15        GetJunkList = junkList
16    Else
17        MsgBox "File not found at:" & vbCr & fpath
18    End If
19    Exit Function
errHandler:
     Dim Msg$
     With Err
         Msg = "Error '" & .Number & " " & _
        .Description & "' occurred in " & _
        "Function<GetJunkList> at line # " & IIf(Erl <> 0, " at line " & CStr(Erl) & ".", ".")
     End With
     MsgBox Msg, vbCritical
End Function

Public Function GetMatches(replaceDBPath$, inputFilePath$) As String()
0     On Error GoTo errHandler
1     Dim junks() As String, junkPat$, tmp$, results() As String, pos&, mts As MatchCollection, mt As Match
2     junks = GetJunkList(replaceDBPath)
3     tmp = fso.OpenTextFile(inputFilePath).ReadAll
4
5     With re
6        .Global = True
7        .MultiLine = True
8        .IgnoreCase = True
9        For pos = LBound(junks) To UBound(junks)
10           .Pattern = junkPat
11           junkPat = junks(pos)
12           'replace junk with []
13           tmp = .Replace(tmp, "")
14       Next pos
15
16       'trim lines [if all input data in one line]
17       .Pattern = "^[ \t]*|[ \t]*$"
18       tmp = .Replace(tmp, "")
19
20       'create array using provided pattern
21       pos = 0
22       .Pattern = "\b[a-z]*[\d]+\-*\d*[a-z0-9]*\b"
23       Set mts = .Execute(tmp)
24       ReDim results(mts.Count - 1)
25       For Each mt In mts
26           results(pos) = mt.Value
27           pos = pos + 1
28       Next mt
29    End With
30
31    GetMatches = results
32    Exit Function
errHandler:
     Dim Msg$
     With Err
         Msg = "Error '" & .Number & " " & _
        .Description & "' occurred in " & _
        "Function<GetMatches> at line # " & IIf(Erl <> 0, " at line " & CStr(Erl) & ".", ".")
     End With
     MsgBox Msg, vbCritical
End Function

そしてサンプルテスター

Public Sub tester()
    Dim samples() As String, s
    samples = GetMatches("C:\Documents and Settings\Cylian\Desktop\junks.lst", "C:\Documents and Settings\Cylian\Desktop\sample.txt")
    For Each s In samples
        MsgBox s
    Next
End Sub

から呼び出される可能性がありますimmediate window

tester

お役に立てれば。

于 2012-05-30T06:07:34.900 に答える