blob: 753562742b8df3ad727d8374178a930857b7f0b8 [file] [log] [blame]
Nils Diewalda31a5152015-04-17 21:05:23 +00001% layout 'main', title => 'KorAP: Poliqarp+';
2
Akron1120a582017-10-17 12:29:16 +02003<h2 id="tutorial-top">Poliqarp+</h2>
Nils Diewalda31a5152015-04-17 21:05:23 +00004
5<p>The following tutorial introduces all features provided by our version of the Poliqarp Query Language and some KorAP specific extensions.</p>
6
Nils Diewaldfccfbcb2015-04-29 20:48:19 +00007<section id="segments">
Nils Diewalda31a5152015-04-17 21:05:23 +00008 <h3>Simple Segments</h3>
9
10 <p>The atomic elements of Poliqarp queries are segments. Most of the time segments represent words and can be simply queried:</p>
11 %# footnote: In the polish national corpus, Poliqarp can join multiple segments when identifying a single word.
12
Akrona7cfd902017-12-21 19:28:36 +010013 %= doc_query poliqarp => loc('Q_poliqarp_simple', 'Tree')
Nils Diewalda31a5152015-04-17 21:05:23 +000014
15 <p>Sequences of simple segments are expressed using a space delimiter:</p>
16
Akrona7cfd902017-12-21 19:28:36 +010017 %= doc_query poliqarp => loc('Q_poliqarp_simpleseq', 'the Tree')
Nils Diewalda31a5152015-04-17 21:05:23 +000018
19 <p>Simple segments always refer to the surface form of a word. To search for surface forms without case sensitivity, you can use the <code>/i</code> flag.</p>
20
Akrona7cfd902017-12-21 19:28:36 +010021 %= doc_query poliqarp => loc('Q_poliqarp_simpleci', 'run/i')
Nils Diewalda31a5152015-04-17 21:05:23 +000022
Akrona7cfd902017-12-21 19:28:36 +010023 <p>The query above will find all occurrences of the term irrespective of the capitalization of letters.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000024
Nils Diewaldfccfbcb2015-04-29 20:48:19 +000025 <h4 id="regexp">Regular Expressions</h4>
Nils Diewalda31a5152015-04-17 21:05:23 +000026
Nils Diewald61e6ff52015-05-07 17:26:50 +000027 <p>Segments can also be queried using <%= doc_link_to 'regular expressions', 'ql', 'regexp' %> - by surrounding the segment with double quotes.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000028
Nils Diewald61e6ff52015-05-07 17:26:50 +000029 %= doc_query poliqarp => '"l(au|ie)fen"'
Nils Diewalda31a5152015-04-17 21:05:23 +000030
Akron54740182017-06-17 14:17:23 +020031 <p>Regular expression segments will always match the whole segment, meaning the above query will find words starting with <code>l</code> and ending with <code>n</code>. To support subqueries, you can use the <code>/x</code> flag.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000032
Nils Diewald61e6ff52015-05-07 17:26:50 +000033 %= doc_query poliqarp => '"l(au|ie)fen"/x', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +000034
35 <p>The <code>/x</code> will search for all segments that contain a sequence of characters the regular expression matches. That means the above query is equivalent to:</p>
36
Nils Diewald61e6ff52015-05-07 17:26:50 +000037 %= doc_query poliqarp => '".*?l(au|ie)fen.*?"', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +000038
39 <p>The <code>/x</code> flag can also be used in conjuntion with strict expressions to search for substrings:</p>
40
Nils Diewald61e6ff52015-05-07 17:26:50 +000041 %= doc_query poliqarp => 'trenn/xi', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +000042
43 <p>The above query will find all occurrences of segments including the string <code>trenn</code> case insensitive, like &quot;Trennung&quot;, &quot;unzertrennlich&quot;, or &quot;Wettrennen&quot;.</p>
44
45 <blockquote class="warning">
46 <p>Beware: These kinds of queries (with prepended <code>.*</code> expressions) are extremely slow!</p>
47 </blockquote>
48
49 <p>You can again apply the <code>/i</code> flag to search case insensitive.</p>
50
Nils Diewald61e6ff52015-05-07 17:26:50 +000051 %= doc_query poliqarp => '"l(au|ie)fen"/xi', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +000052</section>
53
Nils Diewaldfccfbcb2015-04-29 20:48:19 +000054<section id="complex">
Nils Diewalda31a5152015-04-17 21:05:23 +000055 <h3>Complex Segments</h3>
56
57 <p>Complex segments are expressed in square brackets and contain additional information on the resource of the term under scrutiny by providing key/value pairs, separated by an equal-sign.</p>
58
59 <p>The KorAP implementation of Poliqarp provides three special segment keys: <code>orth</code> for surface forms, <code>base</code> for lemmata, and <code>pos</code> for Part-of-Speech. The following complex query finds all surface forms of <code>Baum</code>.</p>
60 %# There are more special keys in Poliqarp, but KorAP doesn't provide them.
61
Nils Diewald61e6ff52015-05-07 17:26:50 +000062 %= doc_query poliqarp => '[orth=Baum]'
Nils Diewalda31a5152015-04-17 21:05:23 +000063
64 <p>The query is thus equivalent to:</p>
65
Nils Diewald61e6ff52015-05-07 17:26:50 +000066 %= doc_query poliqarp => 'Baum'
Nils Diewalda31a5152015-04-17 21:05:23 +000067
68 <p>Complex segments expect simple expressions as values, meaning that the following expression is valid as well:</p>
69
Nils Diewald61e6ff52015-05-07 17:26:50 +000070 %= doc_query poliqarp => '[orth="l(au|ie)fen"/xi]', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +000071
Nils Diewald61e6ff52015-05-07 17:26:50 +000072 <p>Another special key is <code>base</code>, refering to the lemma annotation of the <%= doc_link_to 'default foundry', 'data', 'annotation' %>.
Nils Diewalda31a5152015-04-17 21:05:23 +000073 The following query finds all occurrences of segments annotated as the lemma <code>Baum</code> by the default foundry.</p>
74
Nils Diewald61e6ff52015-05-07 17:26:50 +000075 %= doc_query poliqarp => '[base=Baum]'
Nils Diewalda31a5152015-04-17 21:05:23 +000076
Nils Diewald61e6ff52015-05-07 17:26:50 +000077 <p>The third special key is <code>pos</code>, refering to the part-of-speech annotation of the <%= doc_link_to 'default foundry', 'data', 'annotation' %>.
Nils Diewalda31a5152015-04-17 21:05:23 +000078 The following query finds all attributive adjectives:</p>
79
Akronf4a7cf42018-01-09 15:58:45 +010080 %= doc_query poliqarp => loc('Q_poliqarp_complexpos', '[pos=ADJA]')
Nils Diewalda31a5152015-04-17 21:05:23 +000081
82 <p>Complex segments requesting further token annotations can have keys following the <code>foundry/layer</code> notation.
Akron54740182017-06-17 14:17:23 +020083 For example to find all occurrences of plural words in the <code>mate</code> foundry, you can search using the following query:</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000084
Nils Diewald61e6ff52015-05-07 17:26:50 +000085 %= doc_query poliqarp => '[mate/m=number:pl]'
Nils Diewalda31a5152015-04-17 21:05:23 +000086
87 <h4>Negation</h4>
Akron54740182017-06-17 14:17:23 +020088 <p>Negation of terms in complex expressions can be expressed by prepending the equal sign or the whole expression with an exclamation mark.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000089
Nils Diewald61e6ff52015-05-07 17:26:50 +000090 %= doc_query poliqarp => '[pos!=ADJA]'
91 %= doc_query poliqarp => '[!pos=ADJA]'
Nils Diewalda31a5152015-04-17 21:05:23 +000092
93 <blockquote class="warning">
94 <p>Beware: Negated complex segments can't be searched solely in the Lucene index.
Nils Diewald61e6ff52015-05-07 17:26:50 +000095 However, they work in case they are part of a <%= doc_link_to 'sequence', 'ql', 'poliqarp-plus#syntagmatic-operators-sequence' %>.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +000096 </blockquote>
97
98 <h4 id="empty-segments">Empty Segments</h4>
99
100 <p>A special segment is the empty segment, that matches every word in the index.</p>
101
Nils Diewald61e6ff52015-05-07 17:26:50 +0000102 %= doc_query poliqarp => '[]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000103
Nils Diewald61e6ff52015-05-07 17:26:50 +0000104 <p>Empty segments are useful to express distances of words by using <%= doc_link_to 'repetitions', 'ql', 'poliqarp-plus#syntagmatic-operators-repetitions' %>.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000105
106 <blockquote class="warning">
107 <p>Beware: Empty segments can't be searched solely in the Lucene index.
Nils Diewald9922edf2015-05-07 20:03:33 +0000108 However, they work in case they are part of a <%= doc_link_to 'sequence', 'ql', 'poliqarp-plus#syntagmatic-operators-sequence' %>.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000109 </blockquote>
110</section>
111
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000112<section id="spans">
Nils Diewalda31a5152015-04-17 21:05:23 +0000113 <h3>Span Segments</h3>
114
115 <p>Not all segments are bound to words - some are bound to concepts spanning multiple words, for example noun phrases, sentences, or paragraphs.
116Span segments can be searched for using angular brackets instead of square brackets.</p>
117
Nils Diewald61e6ff52015-05-07 17:26:50 +0000118 %= doc_query poliqarp => '<xip/c=INFC>'
Nils Diewalda31a5152015-04-17 21:05:23 +0000119
120 <p>Otherwise they can be treated in exactly the same way as simple or complex segments.</p>
121</section>
122
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000123<section id="paradigmatic-operators">
Nils Diewalda31a5152015-04-17 21:05:23 +0000124 <h3>Paradigmatic Operators</h3>
125
126 <p>A complex segment can have multiple properties a token has to fulfill. For example to search for all words with the surface form <code>laufe</code> (no matter if capitalized or not) that have the lemma <code>lauf</code> (and not, for example, <code>laufen</code>, which would indicate a verb or a gerund), you can search for:</p>
127
Nils Diewald61e6ff52015-05-07 17:26:50 +0000128 %= doc_query poliqarp => '[orth=laufe/i & base=Lauf]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000129
130 <p>The ampersand combines multiple properties with a logical AND.
131Terms of the complex segment can be negated as introduced before.</p>
132
Nils Diewald61e6ff52015-05-07 17:26:50 +0000133 %= doc_query poliqarp => '[orth=laufe/i & base!=Lauf]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000134
135 <p>The following query is therefore equivalent:</p>
136
Nils Diewald61e6ff52015-05-07 17:26:50 +0000137 %= doc_query poliqarp => '[orth=laufe & !base=Lauf]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000138
139 <p>Alternatives can be expressed by using the pipe symbol:</p>
140
Nils Diewald61e6ff52015-05-07 17:26:50 +0000141 %= doc_query poliqarp => '[base=laufen | base=gehen]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000142
143 <p>All these sub expressions can be grouped using round brackets to form complex boolean expressions:</p>
144
Nils Diewald61e6ff52015-05-07 17:26:50 +0000145 %= doc_query poliqarp => '[(base=laufen | base=gehen) & tt/pos=VVFIN]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000146</section>
147
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000148<section id="syntagmatic-operators">
Nils Diewalda31a5152015-04-17 21:05:23 +0000149 <h3>Syntagmatic Operators</h3>
150
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000151 <h4 id="syntagmatic-operators-sequence">Sequences</h4>
Nils Diewalda31a5152015-04-17 21:05:23 +0000152
153 <p>Sequences can be used to search for segments in order. For example to search for the word &quot;alte&quot; preceded by &quot;der&quot; and followed by &quot;Mann&quot;, you can simple search for the sequence of simple expressions separated by whitespaces.</p>
154
Nils Diewald61e6ff52015-05-07 17:26:50 +0000155 %= doc_query poliqarp => 'der alte Mann'
Nils Diewalda31a5152015-04-17 21:05:23 +0000156
157 <p>However, you can obviously search using complex segments as well:</p>
158
Nils Diewald61e6ff52015-05-07 17:26:50 +0000159 %= doc_query poliqarp => '[orth=der][orth=alte][orth=Mann]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000160
161 <p>Now you may see the benefit of the empty segment to search for words you don't know:</p>
162
Nils Diewald61e6ff52015-05-07 17:26:50 +0000163 %= doc_query poliqarp => '[orth=der][][orth=Mann]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000164
165 <p>You are also able to mix segments and spans in sequences, for example to search for the word &quot;Der&quot; at the beginning of a sentence (which can be interpreted as the first word after the end of a sentence).</p>
166
Akrond05e2112016-02-18 15:47:18 +0100167 %= doc_query poliqarp => '<base/s=s>[orth=Der]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000168
169 <h4>Groups</h4>
170
171 ...
172
173 <h4>Alternation</h4>
174
175 <p>Alternations allow for searching alternative segments or sequences of segments, similar to the paradigmatic operator. You already have seen that you can search for both sequences of <code>der alte Mann</code> and <code>der junge Mann</code> by typing in:</p>
176
Nils Diewald61e6ff52015-05-07 17:26:50 +0000177 %= doc_query poliqarp => 'der [orth=alte | orth=junge] Mann'
Nils Diewalda31a5152015-04-17 21:05:23 +0000178
179 <p>However, this formulation has problems in case you want to search for alternations of sequences rather than terms. If you want to search for both sequences of <code>dem jungen Mann</code> and <code>der alte Mann</code> you can use syntagmatic alternations and groups:</p>
180
Nils Diewald61e6ff52015-05-07 17:26:50 +0000181 %= doc_query poliqarp => '(dem jungen | der alte) Mann'
Nils Diewalda31a5152015-04-17 21:05:23 +0000182
183 <p>The pipe symbol works the same way as with the paradigmatic alternation, but supports sequences of different length as operands. The above query for <code>der alte Mann</code> and <code>der junge Mann</code> can therefor be reformulated as:</p>
184
Nils Diewald61e6ff52015-05-07 17:26:50 +0000185 %= doc_query poliqarp => 'der (junge | alte) Mann'
Nils Diewalda31a5152015-04-17 21:05:23 +0000186
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000187 <h4 id="syntagmatic-operators-repetitions">Repetition</h4>
Nils Diewalda31a5152015-04-17 21:05:23 +0000188
Nils Diewald61e6ff52015-05-07 17:26:50 +0000189 <p>Repetitions in Poliqarp are realized as in <%= doc_link_to 'regular expressions', 'ql', 'regexp' %>, by giving quantifieres in curly brackets.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000190 <p>To search for a sequence of three occurrences of <code>der</code>, you can formulate your query in any of the following ways - they will have the same results:</p>
191
Nils Diewald61e6ff52015-05-07 17:26:50 +0000192 %= doc_query poliqarp => 'der der der'
193 %= doc_query poliqarp => 'der{3}'
194 %= doc_query poliqarp => '[orth=der]{3}'
Nils Diewalda31a5152015-04-17 21:05:23 +0000195
196 <p>In difference to regular expressions, the repetition operation won't refer to the match but to the pattern given. So the following query will give you a sequence of three words having the term <code>der</code> as a substring - but the words don't have to be identical. The following query for example will match a sequence of three words all starting with <code>la</code>.</p>
197
Nils Diewald61e6ff52015-05-07 17:26:50 +0000198 %= doc_query poliqarp => '"la.*?"/i{3}'
Nils Diewalda31a5152015-04-17 21:05:23 +0000199
200 <p>The same is true for annotations. The following query will find a sequence of 3 to 4 adjectives as annotated by the TreeTagger foundry, that is preceded by the lemma <code>ein</code> as annotated by the default foundry and followed by a noun as annotated by the XIP foundry. The adjectives do not have to be identical though.</p>
201
Nils Diewald61e6ff52015-05-07 17:26:50 +0000202 %= doc_query poliqarp => '[base=ein][tt/p=ADJA]{3,4}[xip/p=NOUN]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000203
Akron92e67302017-06-18 20:27:12 +0200204 <p>In addition to numbered quantities, it is also possible to pass repetition information as Kleene operators <code>?</code>, <code>+</code>, and <code>*</code>.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000205
Akron92e67302017-06-18 20:27:12 +0200206 <p>To search for a sequence of the lemma <code>der</code> followed by the lemma <code>baum</code> as annotated by the default foundry, but allowing an optional adjective as annotated by the TreeTagger foundry in between, you can search for:</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000207
Nils Diewald61e6ff52015-05-07 17:26:50 +0000208 %= doc_query poliqarp => '[base=die][tt/pos=ADJA]?[base=Baum]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000209
210 <p>This query is identical to the numbered quantification of:</p>
211
Nils Diewald61e6ff52015-05-07 17:26:50 +0000212 %= doc_query poliqarp => '[base=die][tt/pos=ADJA]{,1}[base=Baum]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000213
214 <p>To search for the same sequences but with unlimited adjectives as annotated by the TreeTagger foundry in between, you can use the Kleene Star:</p>
215
Nils Diewald61e6ff52015-05-07 17:26:50 +0000216 %= doc_query poliqarp => '[base=die][tt/pos=ADJA]*[base=Baum]'
Nils Diewalda31a5152015-04-17 21:05:23 +0000217
218 <p>And to search for this sequence but with at least one adjective in between, you can use the Kleene Plus (all queries are identical):</p>
219
Nils Diewald61e6ff52015-05-07 17:26:50 +0000220 %= doc_query poliqarp => '[base=die][tt/pos=ADJA]+[base=Baum]', cutoff => 1
221 %= doc_query poliqarp => '[base=die][tt/pos=ADJA]{1,}[base=Baum]', cutoff => 1
222 %= doc_query poliqarp => '[base=die][tt/pos=ADJA][tt/pos=ADJA]*[base=Baum]', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000223
224 <blockquote class="warning">
Akron891ce832016-02-24 23:22:06 +0100225 <p>Repetition operators like <code>{,4}</code>, <code>?</code>, and <code>*</code> make segments or groups of segments optional. In case these queries are used separated and not as part of a sequence (and there are no mandatory segments in the query), you will be warned by the system that your query won't be treated as optional.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000226 <p>Keep in mind that optionality may be somehow <i>inherited</i>, for example when you search for <code>(junge|alte)?|tote</code>, one segment of the alternation is optional, which makes the whole query optional as well.</p>
227 </blockquote>
228
Nils Diewald61e6ff52015-05-07 17:26:50 +0000229 <p>Repetition can also be used to express distances between segments by using <%= doc_link_to 'empty segments', 'ql', 'poliqarp-plus#empty-segments' %>.</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000230
Nils Diewald61e6ff52015-05-07 17:26:50 +0000231 %= doc_query poliqarp => '[base=die][][base=Baum]'
232 %= doc_query poliqarp => '[base=die][]{2}[base=Baum]', cutoff => 1
233 %= doc_query poliqarp => '[base=die][]{2,}[base=Baum]', cutoff => 1
234 %= doc_query poliqarp => '[base=die][]{,3}[base=Baum]', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000235
236 <p>Of course, Kleene operators can be used with empty segments as well.</p>
237
Nils Diewald61e6ff52015-05-07 17:26:50 +0000238 %= doc_query poliqarp => '[base=die][]?[base=Baum]'
239 %= doc_query poliqarp => '[base=die][]*[base=Baum]', cutoff => 1
240 %= doc_query poliqarp => '[base=die][]+[base=Baum]', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000241
242 <h4>Position</h4>
243
Nils Diewald61e6ff52015-05-07 17:26:50 +0000244 <p>Sequences as shown above can all be nested in further complex queries and treated as subqueries (see <%= doc_link_to 'class operators', 'ql', 'poliqarp-plus#class-operators' %> on how to later access these subqueries directly).</p>
Nils Diewalda31a5152015-04-17 21:05:23 +0000245 <p>Positional operators compare two matches of subqueries and will match, in case a certain condition regarding the position of both is true.</p>
246 <p>The <code>contains()</code> operation will match, when a second subquery matches inside the span of a first subquery.</p>
247
Akrond05e2112016-02-18 15:47:18 +0100248 %= doc_query poliqarp => 'contains(<base/s=s>, [tt/p=KOUS])', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000249
250 <p>The <code>startsWith()</code> operation will match, when a second subquery matches at the beginning of the span of a first subquery.</p>
251
Akrond05e2112016-02-18 15:47:18 +0100252 %= doc_query poliqarp => 'startsWith(<base/s=s>, [tt/p=KOUS])', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000253
254 <p>The <code>endsWith()</code> operation will match, when a second subquery matches at the end of the span of a first subquery.</p>
255
Akrond05e2112016-02-18 15:47:18 +0100256 %= doc_query poliqarp => 'endsWith(<base/s=s>, [opennlp/p=NN])', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000257
258 <p>The <code>matches()</code> operation will match, when a second subquery has the exact same span of a first subquery.</p>
259
Akrond05e2112016-02-18 15:47:18 +0100260 %= doc_query poliqarp => 'matches(<base/s=s>,[tt/p=CARD][tt/p="N.*"])', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000261
262 <p>The <code>overlaps()</code> operation will match, when a second subquery has an overlapping span with the first subquery.</p>
263
Nils Diewald61e6ff52015-05-07 17:26:50 +0000264 %= doc_query poliqarp => 'overlaps([][tt/p=ADJA],{1:[tt/p=ADJA]}[])', cutoff => 1
Nils Diewalda31a5152015-04-17 21:05:23 +0000265
266 <blockquote class="warning">
267 <p>Positional operators are still experimental and may change in certain aspects in the future (although the behaviour defined is intended to be stable). There is also known incorrect behaviour which will be corrected in future versions.</p>
268 <p>Optional operands in position operators, like in <code>contains(&lt;s&gt;,[orth=Baum]*)</code>, have to be mandatory at the moment and will be reformulated to occur at least once.</p>
269 <p>This behaviour may change in the future.</p>
270 </blockquote>
271
272 <!--
273 <blockquote>
274 <p>The KorAP implementation of Poliqarp also supports the postfix <code>within</code> operator, that works similar to the <code>contains()</code> operator, but is not nestable.</p>
275 </blockquote>
276 -->
277
278</section>
279
Nils Diewaldfccfbcb2015-04-29 20:48:19 +0000280<section id="class-operators">
Nils Diewalda31a5152015-04-17 21:05:23 +0000281 <h3>Class Operators</h3>
282
283 <p>Classes are used to group sub matches by surrounding curly brackets and a class number <code>{1:...}</code>. Classes can be used to refer to sub matches in a query, similar to captures in regular expressions. In Poliqarp+ classes have multiple purposes, with highlighting being the most intuitive one:</p>
284
Nils Diewald61e6ff52015-05-07 17:26:50 +0000285 %= doc_query poliqarp => 'der {1:{2:[]} Mann}'
Nils Diewalda31a5152015-04-17 21:05:23 +0000286
Nils Diewald61e6ff52015-05-07 17:26:50 +0000287 %#= doc_query poliqarp => 'der {1:{2:[]{1,4}} {3:Baum}} {4:[]}'
Nils Diewalda31a5152015-04-17 21:05:23 +0000288
289 <p>In KorAP classes can be defined from 1 to 128. In case a class number is dismissed, the class defaults to the class number 1: <code>{...}</code> is equal to <code>{1:...}</code>.</p>
290
291 <h4>Match Modification</h4>
292
293 <p>Based on classes, matches may be modified. The <code>focus()</code> operator restricts the span of a match to the boundary of a certain class.</p>
294
Nils Diewald61e6ff52015-05-07 17:26:50 +0000295 %= doc_query poliqarp => 'focus(der {Baum})'
Nils Diewalda31a5152015-04-17 21:05:23 +0000296
297 <p>The query above will search for the sequence <code>der Baum</code> but the match will be limited to <code>Baum</code>. You can think of <code>der</code> in this query as a positive look-behind zero-length assertion in regular expressions.</p>
298
299 <p>But focus is way more useful if you are searching for matches without knowing the surface form. For example, to find all terms between the words &quot;der&quot; and &quot;Mann&quot; you can search:</p>
300
Nils Diewald61e6ff52015-05-07 17:26:50 +0000301 %= doc_query poliqarp => 'focus(der {[]} Mann)'
Nils Diewalda31a5152015-04-17 21:05:23 +0000302
303 <p>This will limit the match to all interesting terms in between &quot;der&quot; and &quot;Mann&quot;. Or you may want to search for all words following the sequence &quot;der alte und&quot; immediately:</p>
304
Nils Diewald61e6ff52015-05-07 17:26:50 +0000305 %= doc_query poliqarp => 'focus(der alte und {[]})'
Nils Diewalda31a5152015-04-17 21:05:23 +0000306
307 <!--
308 <p><code>focus()</code> is especially useful if you are searching for matches in certain areas, for example in quotes using positional operators.
309While not being interested in the whole quote as a match, you can focus on what's really relevant to you.</p>
310
Nils Diewald61e6ff52015-05-07 17:26:50 +0000311 %= doc_query poliqarp => 'focus(1:contains(er []{,10} sagte, 1{Baum}))'
Nils Diewalda31a5152015-04-17 21:05:23 +0000312 -->
313
314 <p>In case a class number is dismissed, the focus operator defaults to the class number 1: <code>focus(...)</code> is equal to <code>focus(1: ...)</code>.</p>
315
316 <blockquote class="warning">
317 <p>As numbers in curly brackets can be ambiguous in certain circumstances, for example <code>[]{3}</code> can be read as either &quot;any word repeated three times&quot; or &quot;any word followed by the number 3 highlighted as class number 1&quot;, numbers should always be expressed as <code>[orth=3]</code> for the latter case.</p>
318 </blockquote>
319</section>