Извлечение информации из запроса SPARQL с использованием регулярных выражений

#c# #.net #regex #sparql

#c# #.net #регулярное выражение #sparql

Вопрос:

Мне трудно создать регулярное выражение, которое извлекает пространства имен из этого запроса SPARQL:

 SELECT * 
WHERE {
    ?Vehicle rdf:type umbel-sc:CompactCar ;
             skos:subject <http://dbpedia.org/resource/Category:Vehicles_with_CVT_transmission>;
             dbp-prop:assembly ?Place.
    ?Place geo-ont:parentFeature dbpedia:United_States .
}
  

Мне нужно получить:

 "rdf", "umbel-sc", "skos", "dbp-prop", "geo-ont", "dbpedia"
  

Мне нужно выражение, подобное этому:

 \s ([^\:]*):[^\s] 
  

Но приведенный выше вариант не работает, потому что он также съедает пробелы перед достижением : . Что я делаю не так?

Ответ №1:

Итак, мне нужно выражение, подобное этому:

 \s ([^\:]*):[^\s] 
  

Но приведенный выше вариант не работает, потому что он также съедает пробелы перед достижением «:».

Регулярное выражение будет использовать эти пробелы, да, но группа, заключенная в вашу скобку, не будет содержать их. Это проблема? Вы можете получить доступ к этой группе, прочитав из Groups[1].Value в Match объекте, возвращенном из Regex.Match .

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

 (?<=s)([^:]*):[^s] 
  

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

 Regex.Match(input, @"(?<=s)([^:]*):[^s] ")
  

Ответ №2:

Я не знаю деталей синтаксиса SPARQL, но я бы предположил, что это не обычный язык, поэтому регулярные выражения не смогут сделать это идеально. Однако вы можете подобраться довольно близко, если будете искать что-то похожее на слово, окруженное пробелом слева и двоеточием справа.

Этот метод может быть достаточно хорош для быстрого решения или если ваш формат ввода известен и достаточно ограничен. В качестве более общего решения предлагаю вам поискать или создать подходящий анализатор для языка SPARQL.

С учетом сказанного, попробуйте следующее:

 string s = @"SELECT * 
WHERE {
    ?Vehicle rdf:type umbel-sc:CompactCar ;
    skos:subject <http://dbpedia.org/resource/Category:Vehicles_with_CVT_transmission>;
    dbp-prop:assembly ?Place.
    ?Place geo-ont:parentFeature dbpedia:United_States .
}";

foreach (Match match in Regex.Matches(s, @"s([w-] ):"))
{
    Console.WriteLine(match.Groups[1].Value);
}
  

Результат:

 rdf
umbel-sc
skos
dbp-prop
geo-ont
dbpedia
  

Комментарии:

1. Круто! Это было быстро. Спасибо!

2. @Anton Andreev: Итак … это делает то, что вы хотите? Вы это тестировали?

3. да, но мне пришлось немного изменить это: @»s[*([w-] ):(?!//)» с помощью «[» и, вероятно, будет добавлено больше подобных случаев. Тестирование займет время. Вы можете попробовать для развлечения некоторые запросы SPARQL на веб-сайте моей компании: factforge.net/sparql

4. @Anton Andreev: Я только что заметил, что перед http нет пробела, так что добавленный мной особый случай на самом деле не нужен. Я обновил свой пост, чтобы отразить это.