0

I'm writing a function to "title case" strings e.g. "this is a title" to "This is a Title." The following line doesn't work because the regex group reference is lost (or so I assume). Is there an easy way to uppercase my matching letter in the replace function?

replace( $input, '\b[a-z]' , upper-case('$0'))
4

1 回答 1

1

\b表达式不是 XML Schema 正则表达式的一部分。它被视为只是字符 b,因此您匹配 b 后跟另一个字符。

您在这里的替换字符串upper-case('$0')是公正的$0,因此您正在用它们自己替换字符。

您不能使用替换功能来做到这一点——您需要更像xsl:analyze-string来自 XSLT 的东西,但这在 XQuery 1.0 中不可用。

据我所知,解决这个问题的唯一方法是使用递归函数。如果您不需要保留分隔符,则可以使用使用 tokenize 的更简单的解决方案。

declare function local:title-case($arg as xs:string) as xs:string
{
  if (string-length($arg) = 0)
  then
    ""
  else
    let $first-word := tokenize($arg, "\s")[1]
    let $first := substring($arg, 1, 1)
    return 
      if (string-length($first-word) = 0)
      then
        concat($first, local:title-case(substring($arg, 2)))
      else
        if ($first-word = "a" (: or any other word that should not be capitalized :))
        then
          concat($first-word,
                 local:title-case(substring($arg, string-length($first-word) + 1)))
        else
          concat(upper-case($first),
                 substring($first-word, 2),
                 local:title-case(substring($arg, string-length($first-word) + 1)))
};

您还需要确保每个标题的第一个单词都大写,即使它是像“a”这样的短单词,但我将其留给读者作为练习。

于 2009-12-05T12:32:20.090 回答