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 № 1Jak 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