Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式-应用于文本文件_Regex_Text Processing - Fatal编程技术网

Regex 正则表达式-应用于文本文件

Regex 正则表达式-应用于文本文件,regex,text-processing,Regex,Text Processing,我有一个具有以下结构的文本文件: 关键字0 DataKey01-DataValue01 DataKey02-DataValue02。。。DataKey0N-DataValue0N 关键字1 DataKey11-DataValue11 DataKey12-DataValue12 DataKey13-DataValue13 _________DataKey14-DataValue14 DataKey1N-DataValue1N(1) //重要的是,额外的数据键位于新行上 (1) 下划线不是数据

我有一个具有以下结构的文本文件:

关键字0 DataKey01-DataValue01 DataKey02-DataValue02。。。DataKey0N-DataValue0N


关键字1 DataKey11-DataValue11 DataKey12-DataValue12 DataKey13-DataValue13 _________DataKey14-DataValue14 DataKey1N-DataValue1N(1)

//重要的是,额外的数据键位于新行上
(1) 下划线不是数据的一部分。我用它来对齐数据

问题:如何使用正则表达式将数据转换为这种格式

<KEYWORD0>
    <DataKey00>DataValue00</DataKey00>
    <DataKey01>DataValue01</DataKey01>
    <DataKey02>DataValue02</DataKey02>
    <DataKey0N>DataValue0N</DataKey0N>
</KEYWORD0>
<KEYWORD1>
    <DataKey10>DataValue10</DataKey10>
    <DataKey11>DataValue11</DataKey11>
    <DataKey12>DataValue12</DataKey12>
    <DataKey13>DataValue12</DataKey13>
    <DataKey14>DataValue12</DataKey14>
    <DataKey1N>DataValue1N</DataKey1N>
</KEYWORD1>

数据值00
数据值01
数据值02
数据值0n
数据值10
数据值11
数据值12
数据值12
数据值12
数据值1n
^(\w)\s*(\w)\s*)(\r\n^\s+(\w)\s*))*


这是开始在附近,但我认为这是更容易做到的编程语言。。。只需逐行处理文件

您需要在.NET中使用Regex的组和匹配功能,并应用如下内容:

([A-Z\d]+)(\s([A-Za-z\d]+)\-([A-Za-z\d]+))*
  • 找到匹配项并选择第一个GROUP以查找关键字
  • 循环第3组和第4组的匹配,以捕获该关键字的DataKey和DataValue
  • 转到1

  • 如果DataValue和DataKey项不包含
    或“-”字符或空格,则可以执行以下操作:

    以字符串形式读取您的文件,并使用类似以下正则表达式的replaceAll:
    ([^-\t]+)-([^-\t]+)
    ,并将其用作替换(
    $2
    )。这会将如下内容转换为如下内容:
    DataKey01-DataValue01
    DataValue01

    在此之后,您需要运行另一个全局替换,但此正则表达式
    ^([^\t]+)(\s+(?:]+>[^[\s\n]*)+)
    并再次替换为
    $2

    这应该能奏效

    我不在VB.net中编程,所以我不知道实际语法是否正确(在某些情况下,您可能需要将
    \
    增加一倍或四倍)。您应该确保在第二遍中启用多行选项

    解释:

    ([^- \t]+)-([^- \t]+)
    
    • [^-\t]+
      )将匹配任何不包含
      -
      \t
      的字符字符串。这标记为$1(请注意其周围的括号)
    • -
      将匹配
      -
      字符
    • [^-\t]+
      )将再次匹配不包含
      -
      \t
      的任何字符字符串。这也标记为$2(注意它周围的括号)
    • 替换将只转换与
      cd
      匹配的
      ab cd
      字符串
    执行此步骤后,文件看起来像:

    KEYWORD0 <DataKey00>DataValue00</DataKey00> <DataKey01>DataValue01</DataKey01>
       <DataKey02>DataValue02</DataKey02> <DataKey0N>DataValue0N</DataKey0N>
    
    KEYWORD1 <DataKey10>DataValue10</DataKey10> <DataKey11>DataValue11</DataKey11>
       <DataKey12>DataValue12</DataKey12> <DataKey13>DataValue12</DataKey13>
       <DataKey14>DataValue12</DataKey14> <DataKey1N>DataValue1N</DataKey1N>
    
    关键字0数据值00数据值01
    数据值02数据值0n
    关键字1数据值10数据值11
    数据值12数据值12
    数据值12数据值1N
    
    ^([^\t]+)(\s+(?:]+>[^[\s\n]*)+)

    • ^([^\t]+)
      标记并匹配从行开始的任何非
      \t
      字符串(这是
      $1
    • 开始标记
      • \s+
        空白
      • (?:
        从这里开始的未标记组
        • ]+>
          匹配打开的xml标记:
        • [^
          匹配结束标记
        • [\s\n]*
          一些可选的空白或换行符
      • )+
        关闭未标记的组并至少重复一次
    • 关闭标记(这是
      $2
    替换现在是直接进行的

    希望能有帮助


    但如果这不是一次性的工作,您可能应该尝试制作一个简单的解析器:)

    正则表达式是为受虐狂准备的,它是VB.NET中一个非常简单的文本解析器(从C转换而来,所以请检查bug):

    公共类MyFileConverter
    公共子解析(inputFilename作为字符串,outputFilename作为字符串)
    将读卡器用作新的StreamReader(inputFilename)
    将writer用作新的StreamWriter(outputFilename)
    解析(读写器)
    终端使用
    终端使用
    端接头
    公共子解析(读卡器作为TextReader,写卡器作为TextWriter)
    将线变暗为字符串
    Dim状态为整数=0
    Dim xmlWriter作为新的XmlTextWriter(writer)
    xmlWriter.WriteStartDocument()
    xmlWriter.WriteStarteElement(“关键字”)
    '一致性所需的根元素
    而(InlineAssignHelper(line,reader.ReadLine())不是空的
    如果line.Length=0,则
    如果状态>0,则
    xmlWriter.WriteEndElement()
    如果结束
    状态=0
    继续
    如果结束
    按字符串()的形式对部分进行调整=line.Split(函数(c)[Char].IsWhiteSpace(c),StringSplitOptions.RemoveEmptyEntries)
    作为整数的Dim索引=0
    如果state=0,则
    状态=1
    WriteStarteElement(部分(System.Math.Max(System.Threading.interlocated.Increment(index),index-1)))
    如果结束
    而索引0,则
    xmlWriter.WriteEndElement()
    如果结束
    xmlWriter.WriteEndElement()
    xmlWriter.WriteEndDocument()
    端接头
    InlineAssignHelper(Of T)中的私有共享函数(ByRef目标为T,值为T)为T
    目标=价值
    返回值
    端函数
    末级
    
    注意,我在XML中添加了一个根元素,因为.NETXML对象只喜欢读写一致的XML

    还要注意,代码使用了。

    是否有特定的pr
    Public Class MyFileConverter
        Public Sub Parse(inputFilename As String, outputFilename As String)
            Using reader As New StreamReader(inputFilename)
                Using writer As New StreamWriter(outputFilename)
                    Parse(reader, writer)
                End Using
            End Using
        End Sub
    
        Public Sub Parse(reader As TextReader, writer As TextWriter)
            Dim line As String
            Dim state As Integer = 0
    
            Dim xmlWriter As New XmlTextWriter(writer)
            xmlWriter.WriteStartDocument()
            xmlWriter.WriteStartElement("Keywords")
            ' Root element required for conformance
            While (InlineAssignHelper(line, reader.ReadLine())) IsNot Nothing
                If line.Length = 0 Then
                    If state > 0 Then
                        xmlWriter.WriteEndElement()
                    End If
                    state = 0
                    Continue While
                End If
    
                Dim parts As String() = line.Split(Function(c) [Char].IsWhiteSpace(c), StringSplitOptions.RemoveEmptyEntries)
                Dim index As Integer = 0
    
                If state = 0 Then
                    state = 1
                    xmlWriter.WriteStartElement(parts(System.Math.Max(System.Threading.Interlocked.Increment(index),index - 1)))
                End If
    
                While index < parts.Length
                    Dim keyvalue As String() = parts(index).Split("-"C)
                    xmlWriter.WriteStartElement(keyvalue(0))
                    xmlWriter.WriteString(keyvalue(1))
                    xmlWriter.WriteEndElement()
                    index += 1
                End While
            End While
    
            If state > 0 Then
                xmlWriter.WriteEndElement()
            End If
            xmlWriter.WriteEndElement()
            xmlWriter.WriteEndDocument()
        End Sub
        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
            target = value
            Return value
        End Function
    End Class