Сделать первую букву результирующего набора заглавной

У меня есть этот код SPARQL, предназначенный для работы с Викиданными:

SELECT
  ?game
  (group_concat(distinct      ?gameLabel ; separator = ", ") AS      ?gameLabels)
  (group_concat(distinct     ?genreLabel ; separator = ", ") AS     ?genreLabels)
  WHERE {
    ?game wdt:P31 wd:Q7889;
    wdt:P136 wd:Q744038.
    OPTIONAL {?game wdt:P136     ?genre}
    SERVICE wikibase:label {
      bd:serviceParam wikibase:language "en".
           ?game rdfs:label      ?gameLabel.
          ?genre rdfs:label     ?genreLabel.
    }
  }
GROUP BY $game
ORDER BY ASC (?gameLabels)

Вы можете протестировать код здесь:

https://query.wikidata.org/

Предположим, что ?genreLabel по умолчанию всегда в нижнем регистре. Как сделать первую букву каждого возвращаемого значения заглавной? Спасибо.


person posfan12    schedule 28.05.2017    source источник


Ответы (1)


Это момент, когда все становится сложнее с волшебным ярлыком SERVICE для Викиданных, потому что вы не можете использовать их в частях BIND - или, по крайней мере, я не знаю, как:

SELECT
  ?game
  (group_concat(distinct      ?gameLabel ; separator = ", ") AS      ?gameLabels)
  (group_concat(distinct     ?genreL ; separator = ", ") AS     ?genreLabels)

  WHERE {
    ?game wdt:P31 wd:Q7889 ;
          wdt:P136 wd:Q744038 .
    OPTIONAL {
       ?game wdt:P136     ?genre. 
       ?genre rdfs:label ?gL. 
       FILTER(LANGMATCHES(LANG(?gL), "en"))
    }
    BIND(CONCAT(UCASE(SUBSTR(?gL, 1, 1)), SUBSTR(?gL, 2)) as ?genreL)

    SERVICE wikibase:label {
      bd:serviceParam wikibase:language "en".
           ?game rdfs:label      ?gameLabel.
    }

  }
GROUP BY ?game
ORDER BY ASC (?gameLabels)

Идея заключается в следующем:

  • возьмите первый символ метки: SUBSTR(?gL, 1, 1)
  • примените к нему оператор верхнего регистра: UCASE(SUBSTR(?gL, 1, 1))
  • взять всю строку, начиная со второго символа: SUBSTR(?gL, 2))
  • объединить обе части: CONCAT(UCASE(SUBSTR(?gL, 1, 1)), SUBSTR(?gL, 2))

Обратите внимание, что в какой-то момент может быть проще выполнять модификацию и стиль String на стороне клиента...

person UninformedUser    schedule 28.05.2017
comment
Это немного не по теме, но некоторые названия игр на английском, британском английском и канадском английском. (Понятия не имею, почему.) Как фильтровать только обычный английский с помощью команды LANGMATCHES? FILTER(LANGMATCHES(LANG(...), "en")) кажется недостаточным. Спасибо. - person posfan12; 28.05.2017
comment
Верно, функции LANGMATCHES используются для того, чтобы быть независимыми в отношении диапазона для языка, т. е. они соответствуют британскому английскому, а также американскому английскому и т. д. Чтобы избежать этих дубликатов, просто не используйте LANGMATCHES, т. е. FILTER(LANG(?gL) = "en") - person UninformedUser; 28.05.2017