Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-python/src/expr/string.rs
8336 views
1
use polars::prelude::*;
2
use pyo3::prelude::*;
3
4
use super::datatype::PyDataTypeExpr;
5
use crate::PyExpr;
6
use crate::conversion::Wrap;
7
use crate::error::PyPolarsErr;
8
9
#[pymethods]
10
impl PyExpr {
11
fn str_join(&self, delimiter: &str, ignore_nulls: bool) -> Self {
12
self.inner
13
.clone()
14
.str()
15
.join(delimiter, ignore_nulls)
16
.into()
17
}
18
19
#[pyo3(signature = (format, strict, exact, cache))]
20
fn str_to_date(&self, format: Option<String>, strict: bool, exact: bool, cache: bool) -> Self {
21
let format = format.map(|x| x.into());
22
23
let options = StrptimeOptions {
24
format,
25
strict,
26
exact,
27
cache,
28
};
29
self.inner.clone().str().to_date(options).into()
30
}
31
32
#[pyo3(signature = (format, time_unit, time_zone, strict, exact, cache, ambiguous))]
33
fn str_to_datetime(
34
&self,
35
format: Option<String>,
36
time_unit: Option<Wrap<TimeUnit>>,
37
time_zone: Wrap<Option<TimeZone>>,
38
strict: bool,
39
exact: bool,
40
cache: bool,
41
ambiguous: Self,
42
) -> Self {
43
let format = format.map(|x| x.into());
44
let time_zone = time_zone.0;
45
46
let options = StrptimeOptions {
47
format,
48
strict,
49
exact,
50
cache,
51
};
52
self.inner
53
.clone()
54
.str()
55
.to_datetime(
56
time_unit.map(|tu| tu.0),
57
time_zone,
58
options,
59
ambiguous.inner,
60
)
61
.into()
62
}
63
64
#[pyo3(signature = (format, strict, cache))]
65
fn str_to_time(&self, format: Option<String>, strict: bool, cache: bool) -> Self {
66
let format = format.map(|x| x.into());
67
68
let options = StrptimeOptions {
69
format,
70
strict,
71
cache,
72
exact: true,
73
};
74
self.inner.clone().str().to_time(options).into()
75
}
76
77
fn str_strip_chars(&self, matches: Self) -> Self {
78
self.inner.clone().str().strip_chars(matches.inner).into()
79
}
80
81
fn str_strip_chars_start(&self, matches: Self) -> Self {
82
self.inner
83
.clone()
84
.str()
85
.strip_chars_start(matches.inner)
86
.into()
87
}
88
89
fn str_strip_chars_end(&self, matches: Self) -> Self {
90
self.inner
91
.clone()
92
.str()
93
.strip_chars_end(matches.inner)
94
.into()
95
}
96
97
fn str_strip_prefix(&self, prefix: Self) -> Self {
98
self.inner.clone().str().strip_prefix(prefix.inner).into()
99
}
100
101
fn str_strip_suffix(&self, suffix: Self) -> Self {
102
self.inner.clone().str().strip_suffix(suffix.inner).into()
103
}
104
105
fn str_slice(&self, offset: Self, length: Self) -> Self {
106
self.inner
107
.clone()
108
.str()
109
.slice(offset.inner, length.inner)
110
.into()
111
}
112
113
fn str_head(&self, n: Self) -> Self {
114
self.inner.clone().str().head(n.inner).into()
115
}
116
117
fn str_tail(&self, n: Self) -> Self {
118
self.inner.clone().str().tail(n.inner).into()
119
}
120
121
fn str_to_uppercase(&self) -> Self {
122
self.inner.clone().str().to_uppercase().into()
123
}
124
125
fn str_to_lowercase(&self) -> Self {
126
self.inner.clone().str().to_lowercase().into()
127
}
128
129
#[cfg(feature = "nightly")]
130
fn str_to_titlecase(&self) -> Self {
131
self.inner.clone().str().to_titlecase().into()
132
}
133
134
fn str_len_bytes(&self) -> Self {
135
self.inner.clone().str().len_bytes().into()
136
}
137
138
fn str_len_chars(&self) -> Self {
139
self.inner.clone().str().len_chars().into()
140
}
141
142
#[cfg(feature = "regex")]
143
fn str_replace_n(&self, pat: Self, val: Self, literal: bool, n: i64) -> Self {
144
self.inner
145
.clone()
146
.str()
147
.replace_n(pat.inner, val.inner, literal, n)
148
.into()
149
}
150
151
#[cfg(feature = "regex")]
152
fn str_replace_all(&self, pat: Self, val: Self, literal: bool) -> Self {
153
self.inner
154
.clone()
155
.str()
156
.replace_all(pat.inner, val.inner, literal)
157
.into()
158
}
159
160
fn str_normalize(&self, form: Wrap<UnicodeForm>) -> Self {
161
self.inner.clone().str().normalize(form.0).into()
162
}
163
164
fn str_reverse(&self) -> Self {
165
self.inner.clone().str().reverse().into()
166
}
167
168
fn str_pad_start(&self, length: PyExpr, fill_char: char) -> Self {
169
self.inner
170
.clone()
171
.str()
172
.pad_start(length.inner, fill_char)
173
.into()
174
}
175
176
fn str_pad_end(&self, length: PyExpr, fill_char: char) -> Self {
177
self.inner
178
.clone()
179
.str()
180
.pad_end(length.inner, fill_char)
181
.into()
182
}
183
184
fn str_zfill(&self, length: PyExpr) -> Self {
185
self.inner.clone().str().zfill(length.inner).into()
186
}
187
188
#[pyo3(signature = (pat, literal, strict))]
189
#[cfg(feature = "regex")]
190
fn str_contains(&self, pat: Self, literal: Option<bool>, strict: bool) -> Self {
191
match literal {
192
Some(true) => self.inner.clone().str().contains_literal(pat.inner).into(),
193
_ => self.inner.clone().str().contains(pat.inner, strict).into(),
194
}
195
}
196
197
#[pyo3(signature = (pat, literal, strict))]
198
#[cfg(feature = "regex")]
199
fn str_find(&self, pat: Self, literal: Option<bool>, strict: bool) -> Self {
200
match literal {
201
Some(true) => self.inner.clone().str().find_literal(pat.inner).into(),
202
_ => self.inner.clone().str().find(pat.inner, strict).into(),
203
}
204
}
205
206
fn str_ends_with(&self, sub: Self) -> Self {
207
self.inner.clone().str().ends_with(sub.inner).into()
208
}
209
210
fn str_starts_with(&self, sub: Self) -> Self {
211
self.inner.clone().str().starts_with(sub.inner).into()
212
}
213
214
fn str_hex_encode(&self) -> Self {
215
self.inner.clone().str().hex_encode().into()
216
}
217
218
#[cfg(feature = "binary_encoding")]
219
fn str_hex_decode(&self, strict: bool) -> Self {
220
self.inner.clone().str().hex_decode(strict).into()
221
}
222
223
fn str_base64_encode(&self) -> Self {
224
self.inner.clone().str().base64_encode().into()
225
}
226
227
#[cfg(feature = "binary_encoding")]
228
fn str_base64_decode(&self, strict: bool) -> Self {
229
self.inner.clone().str().base64_decode(strict).into()
230
}
231
232
#[pyo3(signature = (base, dtype=Some(Wrap(DataType::Int64)), strict=true))]
233
fn str_to_integer(&self, base: Self, dtype: Option<Wrap<DataType>>, strict: bool) -> Self {
234
self.inner
235
.clone()
236
.str()
237
.to_integer(base.inner, dtype.map(|wrap| wrap.0), strict)
238
.into()
239
}
240
241
#[cfg(feature = "extract_jsonpath")]
242
fn str_json_decode(&self, dtype: PyDataTypeExpr) -> Self {
243
self.inner.clone().str().json_decode(dtype.inner).into()
244
}
245
246
#[cfg(feature = "extract_jsonpath")]
247
fn str_json_path_match(&self, pat: Self) -> Self {
248
self.inner.clone().str().json_path_match(pat.inner).into()
249
}
250
251
fn str_extract(&self, pat: Self, group_index: usize) -> Self {
252
self.inner
253
.clone()
254
.str()
255
.extract(pat.inner, group_index)
256
.into()
257
}
258
259
fn str_extract_all(&self, pat: Self) -> Self {
260
self.inner.clone().str().extract_all(pat.inner).into()
261
}
262
263
#[cfg(feature = "extract_groups")]
264
fn str_extract_groups(&self, pat: &str) -> PyResult<Self> {
265
Ok(self
266
.inner
267
.clone()
268
.str()
269
.extract_groups(pat)
270
.map_err(PyPolarsErr::from)?
271
.into())
272
}
273
274
fn str_count_matches(&self, pat: Self, literal: bool) -> Self {
275
self.inner
276
.clone()
277
.str()
278
.count_matches(pat.inner, literal)
279
.into()
280
}
281
282
fn str_split(&self, by: Self) -> Self {
283
self.inner.clone().str().split(by.inner).into()
284
}
285
286
fn str_split_inclusive(&self, by: Self) -> Self {
287
self.inner.clone().str().split_inclusive(by.inner).into()
288
}
289
290
fn str_split_exact(&self, by: Self, n: usize) -> Self {
291
self.inner.clone().str().split_exact(by.inner, n).into()
292
}
293
294
fn str_split_exact_inclusive(&self, by: Self, n: usize) -> Self {
295
self.inner
296
.clone()
297
.str()
298
.split_exact_inclusive(by.inner, n)
299
.into()
300
}
301
302
fn str_splitn(&self, by: Self, n: usize) -> Self {
303
self.inner.clone().str().splitn(by.inner, n).into()
304
}
305
306
#[cfg(feature = "regex")]
307
fn str_split_regex(&self, by: Self, strict: bool) -> Self {
308
self.str_split_regex_with_strict(by, strict)
309
}
310
311
#[cfg(feature = "regex")]
312
fn str_split_regex_inclusive(&self, by: Self, strict: bool) -> Self {
313
self.str_split_regex_inclusive_with_strict(by, strict)
314
}
315
316
#[cfg(feature = "regex")]
317
fn str_split_regex_with_strict(&self, by: Self, strict: bool) -> Self {
318
self.inner
319
.clone()
320
.str()
321
.split_regex(by.inner, strict)
322
.into()
323
}
324
325
#[cfg(feature = "regex")]
326
fn str_split_regex_inclusive_with_strict(&self, by: Self, strict: bool) -> Self {
327
self.inner
328
.clone()
329
.str()
330
.split_regex_inclusive(by.inner, strict)
331
.into()
332
}
333
334
fn str_to_decimal(&self, scale: usize) -> Self {
335
self.inner.clone().str().to_decimal(scale).into()
336
}
337
338
#[cfg(feature = "find_many")]
339
fn str_contains_any(&self, patterns: PyExpr, ascii_case_insensitive: bool) -> Self {
340
self.inner
341
.clone()
342
.str()
343
.contains_any(patterns.inner, ascii_case_insensitive)
344
.into()
345
}
346
#[cfg(feature = "find_many")]
347
fn str_replace_many(
348
&self,
349
patterns: PyExpr,
350
replace_with: PyExpr,
351
ascii_case_insensitive: bool,
352
leftmost: bool,
353
) -> Self {
354
self.inner
355
.clone()
356
.str()
357
.replace_many(
358
patterns.inner,
359
replace_with.inner,
360
ascii_case_insensitive,
361
leftmost,
362
)
363
.into()
364
}
365
366
#[cfg(feature = "find_many")]
367
fn str_extract_many(
368
&self,
369
patterns: PyExpr,
370
ascii_case_insensitive: bool,
371
overlapping: bool,
372
leftmost: bool,
373
) -> Self {
374
self.inner
375
.clone()
376
.str()
377
.extract_many(
378
patterns.inner,
379
ascii_case_insensitive,
380
overlapping,
381
leftmost,
382
)
383
.into()
384
}
385
386
#[cfg(feature = "find_many")]
387
fn str_find_many(
388
&self,
389
patterns: PyExpr,
390
ascii_case_insensitive: bool,
391
overlapping: bool,
392
leftmost: bool,
393
) -> Self {
394
self.inner
395
.clone()
396
.str()
397
.find_many(
398
patterns.inner,
399
ascii_case_insensitive,
400
overlapping,
401
leftmost,
402
)
403
.into()
404
}
405
406
#[cfg(feature = "regex")]
407
fn str_escape_regex(&self) -> Self {
408
self.inner.clone().str().escape_regex().into()
409
}
410
411
#[staticmethod]
412
fn str_format(f_string: String, exprs: Vec<PyExpr>) -> PyResult<Self> {
413
let exprs = exprs.into_iter().map(|e| e.inner).collect::<Vec<_>>();
414
Ok(format_str(&f_string, exprs)
415
.map_err(PyPolarsErr::from)?
416
.into())
417
}
418
}
419
420