/ / xquery - jak wybrać tekst occ. po n-tym wystąpieniu ogranicznika / jak wyodrębnić pierwsze n zdań / ostatnie n zdań - xquery

xquery- jak wybrać tekst occ. po n-tym zdarzeniu ogranicznika / jak wyodrębnić pierwsze n zdania / ostatnie n zdania - xquery

Na stronie internetowej znajduje się div o następującej treści:

<div id="test">
<p> This is first sentence. This is second sentence. This is third sentence. This is 4th sentence. </p>
</div>

Jak mogę uzyskać tekst „To jest drugiezdanie "z powyższego fragmentu HTML? Rozumiem, jak dostać się do div / p, w którym ten tekst jest obecny, ale jak wyodrębnić tylko to konkretne zdanie?

Podobnie, jak wyodrębnić pierwsze 3 zdania? A także, jak wybrać ostatnie 2 zdania? Wreszcie, twoje wyrażenie Xquery powinno działać dla dowolnego typu separatora typu „.” / ”,„ / ”;„ itp...

Odpowiedzi:

2 dla odpowiedzi № 1

Jak mogę uzyskać powyższy tekst „To jest drugie zdanie” Fragment HTML?

tokenize(/div/p, "\.")[2]

Podobnie, jak wyodrębnić pierwsze 3 zdania?

tokenize(/div/p, "\.")[position() le 3]

A także, jak wybrać ostatnie 2 zdania?

tokenize(/div/p, "\.")[position() gt last() -2]

Wreszcie, wyrażenie Xquery powinno działać dla dowolnego typu separatora - lubić "." / ”,„ / ”;„ itp...

Użyj jako drugiego argumentu tokenize() ciąg taki jak: "[.,;]"


3 dla odpowiedzi № 2

Podział w punktach

Posługiwać się fn:tokenize do dekonstrukcji łańcucha.

fn:tokenize(//p, "[.,;]")[2]

Wzorzec może być dowolnym prawidłowym wyrażeniem regularnym, łatwo dopasujesz go do swoich potrzeb. Uważaj na regexowe znaki specjalne.

Dla pierwszych trzech zdań użyj fn:position:

tokenize(//p, "[.,;]")[position() le 3]

Aby uzyskać bardziej ogólną analizę, możesz użyć wyrażeń zakresu:

tokenize(//p, "[.,;]")[position() = (2 to 3)]

Lepsze rozpoznawanie zdań

Nie wszystkie punkty kończą zdania. Dla lepszego wykrywania zdań (choć nadal nie zapisuj we wszystkich przypadkach), możesz wykonać regex-foo:

tokenize(//p, "(?<=[.,;])s+(?=p{Lu})")[2]

Spowoduje to podział na wszystkie znaki spacji (lub wiele znaków, które następują po sobie), które są poprzedzone znakiem z listy powyżej, a po nim wielką literą.

Ostrzeżenia: Lookahead i -behind nie są zawarte w XQuerystandard, a zatem obsługiwany przez każde wdrożenie. Korzystanie z niego może być niebezpieczne, nawet jeśli jest obsługiwane, ponieważ narusza to standard i może zostać usunięte. Użyłem do tego BaseX 7.1.1.


2 dla odpowiedzi nr 3

co powiesz na użycie wyrażeń regularnych z fn: zamień i przechwytuj grupy?

ma tę zaletę, że sprawia, że ​​czujesz się bardziej źle, używając wyrażeń regularnych zamiast ręcznie tokenizując ciąg = D

let $s := "This is first sentence. This is second sentence. This is third sentence. This is 4th sentence."

let $adjust-this-regex-as-needed := "([ws]+).([ws]+).([ws]+).([ws]+)."
return (
fn:replace($s, $adjust-this-regex-as-needed , "$1"),     (: first sentence :)
fn:replace($s, $adjust-this-regex-as-needed , "$2  $3")  (: last two sentences :)
)

([ws] +). -> oznacza dopasowanie wszystkich liter i spacji do kropki