Что нового

[Данные, строки] Вытащить данные из файла при помощи регулярного выражения

Kasper

Знающий
Сообщения
70
Репутация
8
Здравствуйте, можете пожалуйста помочь с регулярным выражения для того что бы вытащить данные..
Надо с определенного файла вытащить некоторые данные. Вот часть файла:
Код:
<type name="Файлы шрифтов">
		<item>
			<ex>.abf</ex>
			<des>Двоичный файл шрифта Adobe</des>
		</item>
		<item>
			<ex>.acfm</ex>
			<des>Файл измерений шрифта Adobe Composite</des>
		</item>
		<item>
			<ex>.afm</ex>
			<des>Файл метрических данных шрифта Adobe</des>
		</item>
		<item>
			<ex>.amfm</ex>
			<des>Файл измерений шрифта Adobe Multiple</des>
		</item>
		<item>
			<ex>.bdf</ex>
			<des>Шрифт ASCII</des>
		</item>
		<item>
			<ex>.chr</ex>
			<des>Настройка символов шрифтов Borland</des>
		</item>
		<item>
			<ex>.compositefont</ex>
			<des>Композитный файл шрифта Windows</des>
		</item>
		<item>
			<ex>.dfont</ex>
			<des>Файл шрифта Mac OS X</des>
		</item>
		<item>
			<ex>.eot</ex>
			<des>Файл шрифта OpenType</des>
		</item>
		<item>
			<ex>.euf</ex>
			<des>Файл шрифта Private Character Editor</des>
		</item>
		<item>
			<ex>.f3f</ex>
			<des>Файл шрифта Crazy Machines</des>
		</item>
		<item>
			<ex>.fnt</ex>
			<des>Файл шрифта Windows</des>
		</item>
		<item>
			<ex>.fon</ex>
			<des>Файл шрифта</des>
		</item>
		<item>
			<ex>.fot</ex>
			<des>Файл ресурсов шрифта</des>
		</item>
		<item>
			<ex>.gdr</ex>
			<des>Файл шрифта Symbian OS</des>
		</item>
		<item>
			<ex>.gf</ex>
			<des>Файл изображения шрифта METAFONT</des>
		</item>
		<item>
			<ex>.gxf</ex>
			<des>Файл шрифта General CADD Pro</des>
		</item>
		<item>
			<ex>.mcf</ex>
			<des>Определения шрифтов программы Watchtower Library</des>
		</item>
		<item>
			<ex>.nftr</ex>
			<des>Файл шрифта Nintendo DS</des>
		</item>
		<item>
			<ex>.otf</ex>
			<des>Шрифт OpenType</des>
		</item>
		<item>
			<ex>.pcf</ex>
			<des>Шрифт PaintCAD</des>
		</item>
		<item>
			<ex>.pfa</ex>
			<des>ASCII-файл шрифта принтера</des>
		</item>
		<item>
			<ex>.pfb</ex>
			<des>Двоичный файл шрифта для печати</des>
		</item>
		<item>
			<ex>.pfm</ex>
			<des>Файл метрических данных шрифта</des>
		</item>
		<item>
			<ex>.pfr</ex>
			<des>Файл ресурсов портативного шрифта</des>
		</item>
		<item>
			<ex>.pmt</ex>
			<des>Шаблон PageMaker</des>
		</item>
		<item>
			<ex>.sfp</ex>
			<des>Файл шрифта принтера</des>
		</item>
		<item>
			<ex>.t65</ex>
			<des>Шаблон PageMaker</des>
		</item>
		<item>
			<ex>.tfm</ex>
			<des>Файл данных шрифта TeX</des>
		</item>
		<item>
			<ex>.ttc</ex>
			<des>Коллекция шрифтов TrueType</des>
		</item>
		<item>
			<ex>.tte</ex>
			<des>Файл данных шрифта Private Character Editor</des>
		</item>
		<item>
			<ex>.ttf</ex>
			<des>Шрифт TrueType</des>
		</item>
		<item>
			<ex>.vfb</ex>
			<des>Файл шрифта FontLab Studio</des>
		</item>
		<item>
			<ex>.vlw</ex>
			<des>Файл шрифта Processing</des>
		</item>
		<item>
			<ex>.vnf</ex>
			<des>Файл шрифта Type3</des>
		</item>
		<item>
			<ex>.woff</ex>
			<des>Файл шрифта WOFF</des>
		</item>
		<item>
			<ex>.xfn</ex>
			<des>Файл шрифта принтера Corel Ventura</des>
		</item>
		<item>
			<ex>.xft</ex>
			<des>Файл шрифта принтера ChiWriter</des>
		</item>
		<item>
			<ex>.ytf</ex>
			<des>Файл информации о шрифте Google Picasa</des>
		</item>
	</type>
И таких блоков много. Там разное название (<type name="Файлы шрифтов">) и содержания <item></item> (<ex>.abf</ex><des>Двоичный файл шрифта Adobe</des>)
На выходе на получить массив в котором будет name="Файлы шрифтов" , <ex>.abf</ex> , <des>Двоичный файл шрифта Adobe</des>
Пример:
Код:
$Array[0][0] = 'Файлы шрифтов'
$Array[0][1] = 39 ;~Количество элементов но это не обязательно
$Array[1][0] = '.abf'
$Array[1][1] = 'Двоичный файл шрифта Adobe'
$Array[2][0] = '.acfm'
$Array[2][1] = 'Файл измерений шрифта Adobe Composite'
;~....
$Array[38][0] = '.xft'
$Array[38][1] = 'Файл шрифта принтера ChiWriter'
$Array[39][0] = '.ytf'
$Array[39][1] = 'Файл информации о шрифте Google Picasa'
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Re: [Данные, строки] Регулярное вырежение

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Данные правила могут пополняться локальными правилами раздела.
Как правильно называть темы

"[Данные, строки] Регулярное вырежение" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, ваш Администратор.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Дабы не быть голословным. :smile:
Код:
#include<Array.au3>

;~ ; Читаем файл XML

$sXML = @ScriptDir & "\file_name.xml"
$oObj = ObjCreate('MSXml2.DOMDocument')
$oObj.load($sXML)

$oObj.setProperty('SelectionLanguage', 'XPath')

$oNodes = $oObj.selectNodes('//item')

$iDim1 = $oNodes.length + 1
$iDim2 = $oNodes(0).childNodes.length

Global $aFont[$iDim1][$iDim2]

$aFont[0][0] = $oNodes.length
$aFont[0][1] = $oNodes(0).parentNode.attributes(0).text

For $i = 1 To $oNodes.length
	$aFont[$i][0] = $oNodes($i-1).firstChild.text
	$aFont[$i][1] = $oNodes($i-1).lastChild.text
Next

_ArrayDisplay($aFont)
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
У меня почему-то не получилось так как у Garrettа в сегодняшнем коде.
А вот его вчерашний вариант прекрасно работает
Код:
$sXML = FileRead(@ScriptDir & "\fontsfile.xml")
$oObj = ObjCreate('MSXml2.DOMDocument')
$oObj.loadXML($sXML)


Ну и чисто в академических целях.
Код:
#include 'array.au3'

$Text = FileRead("fontsfile.xml")

$pattern = '(?s)(?:<ex>)(.*?)(?:</ex>.*?<des>)(.*?)(?:</des>)'

$timer = TimerInit()
For $t = 0 To 1000
	$aStr=StringRegExp($Text, $pattern, 3)

	Global $n = Floor(UBound($aStr)/2)
	Global $Array[$n+1][2]
	$Array[0][0] = 'Файлы шрифтов'
	$Array[0][1] = $n ;~Количество элементов но это не обязательно

	For $i=0 To $n-1
		$Array[$i+1][0] = $aStr[2*$i]
		$Array[$i+1][1] = $aStr[2*$i+1]
	Next
Next
ConsoleWrite("RegExp timer = "& TimerDiff($timer)/1000 &" sec."&@CRLF)
_ArrayDisplay($Array)

$sXML = FileRead(@ScriptDir & "\fontsfile.xml")
$oObj = ObjCreate('MSXml2.DOMDocument')
$oObj.loadXML($sXML)

$oObj.setProperty('SelectionLanguage', 'XPath')

$timer = TimerInit()
For $t = 0 To 1000
	$oNodes = $oObj.selectNodes('//item')

	$iDim1 = $oNodes.length + 1
	$iDim2 = $oNodes(0).childNodes.length

	Global $aFont[$iDim1][$iDim2]

	$aFont[0][0] = $oNodes.length
	$aFont[0][1] = $oNodes(0).parentNode.attributes(0).text

	For $i = 1 To $oNodes.length
		$aFont[$i][0] = $oNodes($i-1).firstChild.text
		$aFont[$i][1] = $oNodes($i-1).lastChild.text
	Next
Next
ConsoleWrite("XML timer = "& TimerDiff($timer)/1000 &" sec."&@CRLF)
_ArrayDisplay($aFont)

Код:
RegExp timer = 0.226534007811899 sec.
XML timer = 0.571990060454385 sec.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
C2H5OH [?]
У меня почему-то не получилось
Я специально прокомментировал два варианта загрузки документа. :smile:
Код:
$oObj = ObjCreate('MSXml2.DOMDocument')
; $oObj.load("file name") ; load document from the specified XML source
$oObj.loadXML($sXML) ; load the document from a string
 
Автор
K

Kasper

Знающий
Сообщения
70
Репутация
8
Ну по примеру Garrett'a у меня все получилось и его решение лучше так как я писал что это лишь кусочек файла.
И если обрабатывать файл примером C2H5OH то это долго и не совсем то что нужно
Код:
RegExp timer = 46.7715562732095 sec.
А вариант от Garrett'a намного быстрее
Код:
MSXml2.DOMDocument timer = 0.305601064621353 sec.
Код:
#include <Array.au3>
#include <File.au3>

$sXML = 'config.xml'

; Читаем файл XML
$oObj = ObjCreate('MSXml2.DOMDocument')
$oObj.load($sXML ) ; load document from the specified XML source
;~ $oObj.loadXML($sXML) ; load the document from a string
$oObj.setProperty('SelectionLanguage', 'XPath')
$oNodes = $oObj.selectNodes('//type/@name')
Dim $aItems[3][$oNodes.Length]
$i = 0
For $oNode In $oNodes
	$oItems = $oObj.selectNodes('//type[@name = "'&$oNode.text&'"]//item//ex')
	If $i = 0 Then                                                                ;~Эти условия
		ReDim $aItems[$oItems.Length+1][$oNodes.Length] ;~нужны потому 
		$tLength = $oItems.Length+1                                 ;~что в разных
	EndIf                                                                            ;~типах 
	If $oItems.Length+1 > $tLength Then                              ;~разное
		ReDim $aItems[$oItems.Length+1][$oNodes.Length] ;~количество
		$tLength = $oItems.Length+1                                 ;~item'ов
	EndIf                                                                            ;~
	$aItems[0][$i] = $oNode.text
	$j = 1
	For $oItem In $oItems
		$aItems[$j][$i] = $oItem.text
		$j += 1
	Next
	$i += 1
Next
_ArrayDisplay($aItems)


config.xml
 
Верх