Войти

Показать полную графическую версию : Регулярное выражение


LilLoco
26-06-2013, 16:59
Добрый день.

Есть Kml файл вида:

<Placemark>
<name>сельское поселение</name>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#boundary">
<SimpleData name="Name">сельское поселение</SimpleData>
<SimpleData name="OSM_ID">-1848657</SimpleData>
<SimpleData name="ADMIN_LVL">8</SimpleData>
</SchemaData></ExtendedData>
<MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>35.4913424,56.2869627 35.4866097,56.2876573 35.4835114,56.2879249 35.4866098,56.2876573 35.4913424,56.2869627</coordinates></LinearRing></outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>35.389971680241118,56.234632701458445 35.3899716,56.2346327 35.3854169,56.2349689 35.389971680241118,56.234632701458445</coordinates></LinearRing></outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>35.37138496178531,56.235423204282533 35.3713849,56.2354232 35.3704766,56.235525 35.37138496178531,56.235423204282533</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
</Placemark>
ну и так далее...


Нужно написать регулярное выражение чтобы найти все такие блоки. С регулярными выражениями очень туго :( Нужно вытащить все данные (Name, OSM_ID, ADMIN_LVL, Coordinates). Но на данный момент я не могу даже вытащить только <Placemark>.

Пробовал так:

string textOfFile = System.IO.File.ReadAllText(@"boundary.kml");
Regex r = new Regex(@"<Placemark>\d\D*</Placemark>");
MatchCollection matches = r.Matches(textOfFile);

но ничего не находит.
Попробовал немного иначе:

Regex r = new Regex(@"<Placemark>([\s\S]*)</Placemark>");

Находит одно совпадение! Я так понимаю между первым открытием тега и последним закрытием!

Прошу вашей помощи, подскажите как сделать на первом уровне, далее, думаю, сам разберусь.

Спасибо!

mrcnn
26-06-2013, 17:35
Regex(@"<Placemark>.*</Placemark>");

Такой вариант срабатывает?

Iska
26-06-2013, 20:44
LilLoco, если это фактически xml — почему бы не работать с ним соответствующим способом?

pva
26-06-2013, 21:23
вариант mrcnn + включи multiline (ели включается). В зависимости от реализации, может оказаться ещё так

<Placemark>.*($.*)*</Placemark>

а ещё есть не менее эффективный способ, найти 2 тега (открывающий и закрывающий после него).

LilLoco
27-06-2013, 08:09
вариант mrcnn + включи multiline (ели включается) »
Неа, не работает. Ни одного не находит.
найти 2 тега (открывающий и закрывающий после него). »
Имеете ввиду, найти их позиции в тексте, и вытаскивать текст между ними?
если это фактически xml — почему бы не работать с ним соответствующим способом? »
В блоке, где описываются координаты, бывают разные виды (<MultiGeometry><Polygon><outerBoundaryIs><LinearRing>), поэтому думал будет проще находить регулярными выражениями, и, в зависимости от того какие данные, обрабатывать.

lxa85
27-06-2013, 08:32
LilLoco, я поддерживаю Iska. Не изобретай велосипед, посмотри инструментарий работы с xml, проще будет.

LilLoco
27-06-2013, 09:00
lxa85, Iska, Спасибо. Буду разбираться.

Delirium
06-07-2013, 12:29
Согласен с Iska, .Net дает большие возможности по работе с XML и не надо будет мучаться.

LilLoco
08-08-2013, 15:14
Добрый день.
И снова они...регулярные выражения...

Подскажите как составить регулярное выражение для выбора списка элементов так чтобы текст начинался и заканчивался только цифрой, причем цифра может быть всего одна. В середине строки разрешить использовать только цифры, запятую, тире.

Спасибо.
Уж никак не могу подружиться с регулярными выражениями :(

pva
08-08-2013, 20:35
можно так:

^(\d)|(\d[\d\,\-]*\d)$

Если не принудиловка использовать регекспы, пиши алгоритмически - потом тебе же легче будет разбираться

Iska
08-08-2013, 20:58
Так (код на WSH):
Option Explicit

Dim strValue
Dim objMatch


strValue = "aaa0bbb-,-1-,-2-,-ccc-,-3-,-4-,-ddd5-,-6-,-eee-,-7-,-8fff-,-9eee10-,-fff-,-1-,-2-,-3-,-4-,-"

With WScript.CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(?=\d)[\d,-]*\d"

For Each objMatch In .Execute(strValue)
WScript.Echo objMatch.Value
Next
End With

WScript.Quit 0

0
1-,-2
3-,-4
5-,-6
7-,-8
9
10
1-,-2-,-3-,-4?

можно так:
^(\d)|(\d[\d\,\-]*\d)$»
Нельзя: все совпадения будут односимвольными, т.е. будет всегда отрабатывать первая из альтернатив:
^(\d)|(\d[\d\,\-]*\d)$

Добавлено:
pva, проверил ещё раз, поменяв порядок альтернатив. Так:
(\d[\d\,\-]*\d)|(\d)
— работает.

torauma
09-08-2013, 08:26
поэтому думал будет проще находить регулярными выражениями »
Some people, when confronted with a problem, think
“I know, I'll use regular expressions.” Now they have two problems.
Ну точно про Вас сказано :)

LilLoco
09-08-2013, 08:31
пиши алгоритмически - потом тебе же легче будет разбираться »
В смысле просто написать свою функцию проверки?)

— работает. »
Не работает - позволяет ввести сначала запятую.
Так (код на WSH): »
Так тоже нет, так же позволяет внести запятую.

Iska
09-08-2013, 18:43
Не работает - позволяет ввести сначала запятую. »
На WSH — нет:
Option Explicit

Dim strValue
Dim objMatch


strValue = ",-1-,-2-,"

With WScript.CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "(?=\d)[\d,-]*\d"

For Each objMatch In .Execute(strValue)
WScript.Echo objMatch.Value
Next
End With

WScript.Quit 0
1-,-2
А что на VB.Net?

Стоп. Что значит «ввести/внести» в Вашей трактовке?

LilLoco
09-08-2013, 20:16
Ну я имею ввиду, что можно в текстовое поле ввести например ,8,9
А необходимо чтобы первый символ - была только цифра.

Вот как то так.

Прошу прощения за изложение мыслей так "непонятно" - сказывается конец рабочей недели((

pva
09-08-2013, 22:07
Нельзя: все совпадения будут односимвольными, т.е. будет всегда отрабатывать первая из альтернатив: »
Действительно косячно работало. Попробовал вот так:

var re = /^\d$|^\d[\d\,\-]*\d$/;
var test = [
"312321",
"3",
"31,23-21",
"31232,1",
"312321,",
"-,312321",
"3-",
"3-,,,,5",
"3----6",
"-3-"
]

for(i in test) {
WScript.Echo(test[i] + ":\t\t\t" + re.exec(test[i]));
}

Вроде работает:

312321: 312321
3: 3
31,23-21: 31,23-21
31232,1: 31232,1
312321,: null
-,312321: null
3-: null
3-,,,,5: 3-,,,,5
3----6: 3----6
-3-: null

Но это всё implementation-specific

В смысле просто написать свою функцию проверки?) »
Совершенно верно!

Iska
10-08-2013, 00:50
Ну я имею ввиду, что можно в текстовое поле ввести например ,8,9
А необходимо чтобы первый символ - была только цифра. »
LilLoco, так ввод — это совсем другое. Вам маска ввода нужна для поля ввода, а не регулярка. Регулярка, напротив, поможет из введённого бреда попытаться извлечь что-либо подходящее.

Действительно косячно работало. »
Так обратный порядок альтернатив в Вашем примере — работал. Я позже нашёл в документации явное упоминание, что сравнение альтернатив идёт слева направо. Мне же почему-то раньше казалось, что все части равноправны, ан — нет.

LilLoco
11-08-2013, 12:45
Регулярка, напротив, поможет из введённого бреда попытаться извлечь что-либо подходящее. »
В .Net есть метод IsMatch, который, как я понял прочитав в первый раз, проверяет соответствие введенной строки с заданным регулярным выражением. Теперь, Iska, вы открыли мне глаза!

Совершенно верно! »
Так и сделаю.

Видимо регулярные выражения совершенно не для меня :o

pva
11-08-2013, 13:24
LilLoco, Регулярные выражения - очень простая штука. Поиграйся с поиском-заменой в текстовом редакторе (например notepad++) и всё поймёшь. Это очень удобный и для поиска и замены текста инструмент.
Но их функционал ограничивается выявлением шаблона в тексте, не более. Например регулярным выражением нельзя выяснить, что диапазон 999-100 задан неверно.
А кодом, например, можно сделать как на скриншоте (аттач)

Niaz
04-05-2016, 09:36
Ребята, не подскажите, как можно сделать заливку этого участка по координатам?
Или залить участок с прозрачностью 50%. ?

это тут делается? <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>




© OSzone.net 2001-2012