Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/utils/stringutil.py @ 45724:ac39a8a214b1
stringutil: add function to compile stringmatcher pattern into regexp
Prepares for adding a revset predicate for "grep --diff". The grep logic
needs a regexp object instead of a match function.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 05 Oct 2020 20:40:39 +0900 |
parents | edfc5820aae7 |
children | 89a2afe31e82 |
comparison
equal
deleted
inserted
replaced
45723:edfc5820aae7 | 45724:ac39a8a214b1 |
---|---|
374 return kind, pattern, match | 374 return kind, pattern, match |
375 | 375 |
376 raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) | 376 raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) |
377 | 377 |
378 | 378 |
379 def substringregexp(pattern, flags=0): | |
380 """Build a regexp object from a string pattern possibly starting with | |
381 're:' or 'literal:' prefix. | |
382 | |
383 helper for tests: | |
384 >>> def test(pattern, *tests): | |
385 ... regexp = substringregexp(pattern) | |
386 ... return [bool(regexp.search(t)) for t in tests] | |
387 >>> def itest(pattern, *tests): | |
388 ... regexp = substringregexp(pattern, remod.I) | |
389 ... return [bool(regexp.search(t)) for t in tests] | |
390 | |
391 substring matching (no prefix): | |
392 >>> test(b'bcde', b'abc', b'def', b'abcdefg') | |
393 [False, False, True] | |
394 | |
395 substring pattern should be escaped: | |
396 >>> substringregexp(b'.bc').pattern | |
397 '\\\\.bc' | |
398 >>> test(b'.bc', b'abc', b'def', b'abcdefg') | |
399 [False, False, False] | |
400 | |
401 regex matching ('re:' prefix) | |
402 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar') | |
403 [False, False, True] | |
404 | |
405 force substring matches ('literal:' prefix) | |
406 >>> test(b'literal:re:foobar', b'foobar', b're:foobar') | |
407 [False, True] | |
408 | |
409 case insensitive literal matches | |
410 >>> itest(b'BCDE', b'abc', b'def', b'abcdefg') | |
411 [False, False, True] | |
412 | |
413 case insensitive regex matches | |
414 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar') | |
415 [False, False, True] | |
416 """ | |
417 kind, pattern = _splitpattern(pattern) | |
418 if kind == b're': | |
419 try: | |
420 return remod.compile(pattern, flags) | |
421 except remod.error as e: | |
422 raise error.ParseError( | |
423 _(b'invalid regular expression: %s') % forcebytestr(e) | |
424 ) | |
425 elif kind == b'literal': | |
426 return remod.compile(remod.escape(pattern), flags) | |
427 | |
428 raise error.ProgrammingError(b'unhandled pattern kind: %s' % kind) | |
429 | |
430 | |
379 def shortuser(user): | 431 def shortuser(user): |
380 """Return a short representation of a user name or email address.""" | 432 """Return a short representation of a user name or email address.""" |
381 f = user.find(b'@') | 433 f = user.find(b'@') |
382 if f >= 0: | 434 if f >= 0: |
383 user = user[:f] | 435 user = user[:f] |