2016-10-24 5 views
2

多くの言語で、正規表現キャプチャグループを1つ以上の変数に割り当てることができます。これもXQueryのケースですか?私たちが今までに得た最高のものは、「キャプチャグループで置き換える」ことですが、それは最もきわめて簡単な選択肢ではありません。XQueryの変数にキャプチャグループを割り当てます。

これは、我々が今持っているものです。

let $text := fn:replace($id, '(.+)(\d+)', '$1'); 
let $snr := fn:replace($id, '(.+)(\d+)', '$2'); 

働きます。しかし、私はそこにこのようなものがあることを望んでいたでしょう:

let ($text, $snr) := fn:matches($id, '(.+)(\d+)'); 

それ(またはそれに類するもの)は存在しますか?

答えて

2

プレーンXQuery 1.0では、一致するグループを返す機能がありません。この欠点はXQuery function library which provides functx:get-matchesで解決されていますが、実装は効率的とはみなされません。

XQuery 3.0は、非常に強力な関数fn:analyze-stringを認識しています。この関数は、一致する部分と一致しない部分の両方を返します。また、一致する部分が正規表現で定義されている場合は分割します。

上記のリンクMarklogicのドキュメントからの例が、機能は標準のXPath/XQueryの3.0関数ライブラリから他のXQuery 3.0の実装のためにも利用できるとです:あなたは、XQueryのサポートを持っていない場合

fn:analyze-string('Tom Jim John',"((Jim) John)") 

=> 
<s:analyze-string-result> 
    <s:non-match>Tom </s:non-match> 
    <s:match> 
    <s:group nr="1"> 
    <s:group nr="2">Jim</s:group> 
    John 
    </s:group> 
    </s:match> 
</s:analyze-string-result> 

3.0:いくつかのエンジンは、同様の実装定義関数を提供するか、Javaコードのようなバックエンド関数を使用できるようにしています。この場合、XQueryエンジンのドキュメントを読んでください。

0

あなたは、特定の文字がキャプチャグループ内で発生していないわかっている場合は、グループ間でその文字に置き換え、その後、例えば、XQueryの1

でそれにトークン化を使用することができます

tokenize(replace("abc1234", "(.+)(\d+)", "$1-$2"), "-") 
あなたが使用して機能にそれを一般化することができます

tokenize(replace("abc1234", "^.*?(.+?)(\d+).*?$", "$1-$2"), "-") 

Pを置き換える作成した文字列を、参加:グループの後にする前に/

を確認するために置き換えるには、すべてを削除します「$ 1- $ 2 - $ 3 - $ 4」任意の区切りのためのようなattern:

declare function local:get-matches($input, $regex, $separator, $groupcount) { 
    tokenize(replace($input, concat("^.*?", $regex, ".*?$"), string-join(for $i in 1 to $groupcount return concat("$", $i), $separator)), $separator, "q") 
}; 
local:get-matches("abc1234", "(.+?)(\d+)", "|", 2) 

あなたは、セパレータを自分で指定したくない場合は、1を見つけるために、機能を必要としています。入力文字列よりも長いすべての文字列はキャプチャグループには存在しないため、長い文字列を使用して常に1つの文字列を見つけることができます。

関連する問題