【问题标题】:What would be the best way to parse this file?解析此文件的最佳方法是什么?
【发布时间】:2010-09-14 17:38:56
【问题描述】:

我只是想知道是否有人知道我可以解析帖子底部文件的好方法。

我有一个数据库设置,每个部分都有正确的表,例如参考表、呼叫者表、位置表。每个表都有相同的列,显示在下面的文件中

我真的很喜欢具有相当遗传性的东西,所以如果文件布局发生变化,它不会让我感到很困扰。目前我只是一次读取一行文件,并使用 case 语句来检查我在哪个部分。

有人能帮我解决这个问题吗?

附言。我使用的是 VB,但 C# 或其他任何东西都可以,文档中的 x 只是我已空白的个人信息

谢谢, 内森

文件:--->

DIAL BEFORE YOU DIG
Call 1100, Fax 1300 652 077
PO Box 7710 MELBOURNE, VIC 8004

Utilities are requested to respond within 2 working days and reference the Sequence number.

[REFFERAL DETAILS]
FROM=                 Dial Before You Dig - Web
TO=                   Technical Services
UTILITY ID=           xxxxxx
COMPANY=              {Company Name}
ENQUIRY DATE=         02/10/2008 13:53
COMMENCEMENT DATE=    06/10/2008
SEQUENCE NO=          xxxxxxxxx
PLANNING=             No

[CALLER DETAILS]
CUSTOMER ID=          403552
CONTACT NAME=         {Name of Contact}
CONTACT HOURS=        0
COMPANY=              Underground Utility Locating
ADDRESS=              {Address}
SUBURB=               {Suburb}
STATE=                {State}
POSTCODE=             4350
TELEPHONE=            xxxxxxxxxx
MOBILE=               xxxxxxxxxx
FAX TYPE=             Private
FAX NUMBER=           xxxxxxxxxx
PUBLIC ADDRESS=       xxxxxxxxxx
PUBLIC TELEPHONE=
EMAIL ADDRESS=        {Email Address}

[LOCATION DETAILS]
ADDRESS=              {Location Address}
SUBURB=               {Location Suburb}
STATE=                xxx
POSTCODE=             xxx
DEPOSITED PLAN NO=    0
SECTION & HUNDRED NO= 0
PROPERTY PHONE NO=
SIDE OF STREET=       B
INTERSECTION=         xxxxxx
DISTANCE=             0-200m B
ACTIVITY CODE=        15
ACTIVITY DESCRIPTION= xxxxxxxxxxxxxxxxxx
MAP TYPE=             StateGrid
MAP REF=              Q851_63
MAP PAGE=
MAP GRID 1=
MAP GRID 2=
MAP GRID 3=
MAP GRID 4=
MAP GRID 5=
GPS X COORD=
GPS Y COORD=
PRIVATE/ROAD/BOTH=    B
TRAFFIC AFFECTED=     No
NOTIFICATION NO=      3082321
MESSAGE=              entire intersection of Allora-Clifton rd , Hillside
rd and merivale st

MOCSMESSAGE=          Digsafe generated referral

Notice: Please DO NOT REPLY TO THIS EMAIL as it has been automatically generated and replies are not monitored. Should you wish to advise Dial Before You Dig of any issues with this enquiry, please Call 1100

(See attached file: 3082321_LLGDA94.GML)

【问题讨论】:

    标签: vb.net parsing fileparse


    【解决方案1】:

    Google has the answers,一旦您知道文件格式称为“.ini”

    编辑:也就是说,它是一个 .ini 加上一些额外的前导/尾随 gunk。

    【讨论】:

    • 它看起来像一个 .ini,除了最后一行之外,它似乎只是非结构化文本。
    • 哦,还有前四行。
    • 没错,它看起来确实需要修剪前导/尾随粘液。
    • 它是通过电子邮件发送到正文中的,所以它不是一个 ini 文件,即使它看起来像一个 :)
    • grep for /\=|^[.*]$/ 首先应该摆脱垃圾,对吧?
    【解决方案2】:

    您可以按顺序读取文件的每一行。每一行本质上是一个名称值对。将每个值放在以名称为键的映射(哈希表)中。为每个部分使用地图。完成文件解析后,您将拥有包含所有名称值对的映射。遍历每个地图并填充您的数据库表。

    【讨论】:

      【解决方案3】:

      我会使用 Python 进行任何类型的字符串解析。我不确定您要保留多少这些信息,但我可能会使用 Python 的 split() 函数在 = 上拆分以去除等号,然后从第二部分中去掉空格馅饼。

      首先,我会屏蔽掉我知道不需要的页眉/页脚信息,然后执行类似于以下操作:

      让我们取出一个块并将其保存在test1.txt:

      地址= {位置地址} SUBURB= {位置郊区} 状态 = xxx 邮政编码= xxx 存款计划编号= 0 部分 & 百号 = 0 物业电话号码=

      这是一个小python sn-p:

      >>> f = open("test1.txt", "r") >>> l = f.readlines() >>> l = [line.split('=') for line in l] >>> 对于 l 中的行: 打印线 ['地址', '{位置地址}'] ['郊区','{地点郊区}'] ['状态','xxx'] ['邮政编码','xxx'] ['存款计划号','0'] ['部分和百无','0'] ['物业电话号码', '']

      这实际上会给你一个 [Column, Value] 元组,你可以使用它来将数据插入到数据库中(在转义所有字符串等之后,SQL 注入警告)。

      这是假设电子邮件输入和您的数据库将具有相同的列名,但如果他们没有,那么使用字典设置列映射将相当简单。另一方面,如果电子邮件和列同步,则无需知道列的名称即可进行解析。

      您可以遍历伪字典并在参数化 sql 字符串的正确位置打印出每个键值对。

      希望这会有所帮助!

      编辑:虽然这是在 Python 中,但 C#/VB.net 应该具有相同/相似的能力。

      【讨论】:

      • 您错过了一些“列”在不同的“上下文”中多次出现的事实。例如,POSTCODE 出现在 [CALLER DETAILS] 和 [LOCATION DETAILS] 部分中。
      • 是的,但这可以通过为要插入的不同表制作不同的字典来解决,我认为无论如何这都是明智的。
      【解决方案4】:
      Using f As StreamReader = File.OpenText("sample.txt")
          Dim g As String = "undefined"
          Do
              Dim s As String = f.ReadLine
              If s Is Nothing Then Exit Do
              s = s.Replace(Chr(9), " ")
              If s.StartsWith("[") And s.EndsWith("]") Then
                  g = s.Substring("[".Length, s.Length - "[]".Length)
              Else
                  Dim ss() As String = s.Split(New Char() {"="c}, 2)
                  If ss.Length = 2 Then
                      Console.WriteLine("{0}.{1}={2}", g, Trim(ss(0)), Trim(ss(1)))
                  End If
              End If
          Loop
      End Using
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-30
        • 2022-06-23
        • 2011-12-18
        • 2015-06-14
        • 2011-09-05
        • 2019-09-16
        • 2018-12-16
        相关资源
        最近更新 更多