They are created by placing the characters to be grouped inside a set of parentheses. a(b|c) matches a string that has a followed by b or c (and captures b or c)-> Try it! How do you access the matched groups in a JavaScript regular expression? Photo by Markus Spiske on Unsplash. You can configure Regex to capture Explicit groups only (there is an option for that when you create a regex), or use (?:.*?) Is there some simple way to do this? What is the difference between re.search() and re.findall() methods in Python regular expressions? Also wants to use start/end markers to enforce the check on the whole string. Groups beginning with (? Some of the functions are simplified versions of the full featured methods for compiled regular expressions. Url Validation Regex | Regular Expression - Taha match whole word Match or Validate phone number nginx test Blocking site with unblocked games special characters check Match html tag Match anything enclosed by square brackets. If the sequence is a simple string then a regex is over-complicating things; a contains/indexOf check is the more sensible option. and regexec(®ex, av[1], 1, pmatch, 0); becomes regexec(®ex, av[1], 2, pmatch, 0); The 0th element of the pmatch array of regmatch_t structs will contain the boundaries of the whole string matched, as you have noticed. !regex here). Example. The regex with the capturing group has remembered a backtracking position for the alternation. ^[a-zA-Z0-9]{1,10}@[a-zA-Z0-9]{1,10}. Thanks for contributing an answer to Stack Overflow! The regular expression a (bc | b) c (capturing group) matches abcc and abc. The balancing group makes sure that the regex never matches a string that has more c’s at any point in the string than it has o’s to the left of that point. site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. What is this logical fallacy? If it isn't, it just creates a superfluous addition to the set of available capture group values, inside as well as outside the regexp. On the other hand, regexes are so opaque (if not cryptic), I think it's worthwhile to break the knowledge into smaller, more manageable chunks whenever possible. : in the beginning. Without parentheses, the pattern go+ means g character, followed by o repeated one or more times. What's the difference between どうやら and 何とか? Were the Beacons of Gondor real or animated? However, the library cannot be used with regular expressions that contain non-named capturing groups. Hope it helps. regex documentation: Named Capture Groups. ), My friend says that the story of my novel sounds too similar to Harry Potter. Most non-trivial applications always use the compiled form. A numbered backreference uses the following syntax:\ numberwhere number is the ordinal position of the capturing group in the regular expression. Within the regular expression, you can use the backreference \1 to match the same text that was matched by the capturing group. Were the Beacons of Gondor real or animated? For example, the regular expression (dog) creates a single group containing the letters "d" "o" and "g". Non-Capturing Group only matches the characters but not capture the group . [a-z] matches r which is then stored in the stack for the capturing group “letter” at recursion level zero. If I had thought there would be a noticeable difference between the two approaches, I wouldn't have hesitated to recommend the faster one. However, the regex engine isn’t done yet. It can be used with multiple captured parts. Substituting a Named Group. Captures: Captures represents a group of captured strings for a single match. Matches Here's a code example that demonstrates capturing multiple groups. Captures: Captures represents a group of captured strings for a single match. CaptureNames: An iterator over the names of all possible captures. .*? A sequence of non-metacharacters matches the same sequence in the target string, as we saw above with m/abc/. To learn more, see our tips on writing great answers. Is it ok to use an employers laptop and software licencing for side freelancing work? That is, it does not count as having taken any space. They capture the text matched by the regex inside them into a numbered group that can be reused with a numbered backreference. Named Groups. In your source code, check the name of the header returned in the first capturing group, and then use a second regular expression to validate the contents of the header returned in the second capturing group of the first regex. Is the heat from a flame mainly radiation or convection? 2. basic: The POSIX basic regular expressions or BRE. For more information about named capturing groups, see Grouping Constructs.. What is a non-capturing group in regular expressions? (2)}}) checks if Group 2 has been set. You can reuse the same backreference more than once. RegEx match open tags except XHTML self-contained tags. followed : . If I'm the CEO and largest shareholder of a public company, would taking anything from my office be considered as a theft? First group matches abc. Thank you. These regular expression grammars are defined in std::regex_constants: 1. If you are using GNU grep, and are parsing input, use the '-v' flag to invert your results, returning all non-matches. The C# Regex for simple email validation is. (1):END) checks if Group 1 has been set. in backreferences, in the replace pattern as well as in the following lines of the program. The regex with the atomic group, however, exited from an atomic group after bc was matched. Can't do this if you're using a text editor. abck, etc. rev 2021.1.21.38376, Stack Overflow works best with JavaScript enabled, Where developers & technologists share private knowledge with coworkers, Programming & related technical career opportunities, Recruit tech talent & build your employer brand, Reach developers & technologists worldwide, Here's a version that captures multiple groups in multiple matches, Episode 306: Gaming PCs to heat your home, oceans to cool your data centers, How to validate an email address in JavaScript. (Nothing new under the sun? Groups info. The conditional (? Using a character class such as [^ab] will match a single character that is not within the set of characters. Capturing groups are a way to treat multiple characters as a single unit. You can reuse the same backreference more than once. It matches strings such as "bob" and "boB" But don't get carried away: you cannot blend … ^(?:(?'open'o)+(?'-open'c)+)+(?(open)(?! The one I posted will be efficient enough for most applications. If code is hard to read, leave comments/documentation so they can learn, instead of using lesser code that keeps them ignorant. Url Validation Regex | Regular Expression - Taha Match or Validate phone number nginx test Blocking site with unblocked games Match html tag Find Substring within a string that begins and ends with paranthesis Empty String Match dates (M/D/YY, M/D/YYY, MM/DD/YY, MM/DD/YYYY) Checks the length of number and not starts with 0 all except word For anyone who's interested, I tested with a large chunk of Lorem Ipsum text, counting the number of lines that don't contain the word "quo". How to accomplish? How do you use a variable in a regular expression? hence regmatch_t pmatch[1]; becomes regmatch_t pmatch[2]; How to match “anything up until this sequence of characters” in a regular expression? Regular Expression 2 (re2.h) syntax. :regexp), still allow the regexp to be treated as a single unit, but don't establish a capturing group at the same time. Regex lets you specify substrings with a certain range of … Regular expressions are a notation for describing sets of character strings. Some regular expression flavors allow named capture groups.Instead of by a numerical index you can refer to these groups by name in subsequent code, i.e. By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy. This is denoted by ? a[bc] same as previous, but without capturing b or c Character classes — \d \w \s and . I need 30 amps in a single room to run vegetable grow lighting. They are created by placing the characters to be grouped inside a set of parentheses. For the problem described in the question, it's overkill. in backreferences, in the replace pattern as well as in the following lines of the program. … Match: Match represents a single match of a regex in a haystack. Just bought MacMini M1, not happy with BigSur can I install Catalina and if so how? Regular expressions look something like the below. Why does a simple .*? In general, if I know the exact string I'm looking for, I've found regexes are overkill. A regular expression may have multiple capturing groups. Regular expressions (called REs, or regexes, or regex patterns) are essentially a tiny, highly specialized programming language embedded inside Python and made available through the re module. UPDATE: In the comments below, I stated that this approach is slower than the one given in Peter's answer. grep: use square brackets to match specific characters, Short story about a explorers dealing with an extreme windstorm, natives migrate away. Merge Two Paragraphs with Removing Duplicated Lines. This regex also matches a, b, or c. But it has three capturing groups. This time, it does not apply to a dot but to a non-capturing group (? If number is not defined in the regular expression pattern, a parsing error occurs, and the regular expression engine throws an ArgumentException. non-greedy regex greedily include additional characters before a match? ([abc]) = \1 matches a=a, b=b, and c=c. I'm attempting something which I feel should be fairly obvious to me but it's not. ), Asked to referee a paper on a topic that I think another group is working on. Absolutely true. It does not match anything else. Url Validation Regex | Regular Expression - Taha match whole word Match or Validate phone number nginx test Blocking site with unblocked games Match html tag Match anything enclosed by square brackets. (with REG_EXTENDED cflags), I want to capture everything between '<' and '>'. What is a non-capturing group in regular expressions? Because there is no extraction, non-capturing groupings are faster than capturing groupings. Capturing groups are numbered by counting their opening parentheses from the left to the right. If the capturing group with the given name took part in the match attempt thus far, the “then” … An iterator that yields all non-overlapping capture groups matching a particular regular expression. Some regular expression flavors allow named capture groups.Instead of by a numerical index you can refer to these groups by name in subsequent code, i.e. That has two effects: It allows to get a part of the match as a separate item in the result array. @Blixit: yes, it is. what if I want neither def If name doesn't specify a valid named capturing group defined in the regular expression pattern but … How do you bake out a world space/position normal maps? Let’s see how parentheses work in examples. Short story about a explorers dealing with an extreme windstorm, natives migrate away. Example: gogogo. Since you know you don't want "ab", it's a simple matter to test if the string contains that string, without using regex. your coworkers to find and share information. So it'll match abce, abc, abck, etc. Hexadecimal escape values must be exactly two digits long. Matches For example, "\x41" matches "A". If you count the opening capturing braces in your regular expression you can create a mapping between named capturing groups and the numbered capturing groups in your regex and can mix and match freely. The conditional at the end, which must remain outside t… (With the ^ being the negating part). How can I check if a directory exists in a Bash shell script? In results, matches to capturing groups typically in an array whose members are in the same order as the left parentheses in the capturing group. Combining Non-Capture Group with Inline Modifiers As we saw in the section on non-capture groups, you can blend mode modifiers into the non-capture group syntax in all engines that support inline modifiers—except Python. For instance, if we want to find (go)+, but don’t want the parentheses contents (go) as a … It’s regular expression time again. Are KiCad's horizontal 2.54" pin header and 90 degree pin headers equivalent? After the match, $1 holds a, b, or c. Compare this with the regex (a) | (b) | (c) that lacks the branch reset group. The capturing group took part in the match, so only the “then” part is used. An iterator that yields all non-overlapping capture groups matching a particular regular expression. Other regex tools also have a 'return nonmatch' function, too. :…) that contains an alternation. The C++ standard library as defined in the C++11 standard provides support for regular expressions in the header. ECMAScript: This is closest to the grammar used by JavaScript and the .NET languages. These are the regexes I used: Whether I search for matches in the whole text, or break it up into lines and match them individually, the anchored lookahead consistently outperforms the floating one. Non-capturing groupings, denoted by (? :\\[assembly: AssemblyVersion\\(\"\\d\\.\\d\\.)?.*(?:\"\\)\\])? This property is useful for extracting a part of a string from a match. Instead, it throws an ArgumentException. You can also “or” it with std::regex_constants::nosubs to turn all capturing groups into non-capturing groups, which makes your regex more efficient if you only care about the overall regex match and don’t want to extract text matched by any of the capturing groups. It can be used with multiple captured parts. Prior to C++11, was part of the TR1 extension to the C++ standard library. However, if name is the string representation of a number and the capturing group in that position has been explicitly assigned a numeric name, the regular expression parser cannot identify the capturing group by its ordinal position. Url Validation Regex | Regular Expression - Taha match whole word Match or Validate phone number nginx test Blocking site with unblocked games Match html tag Match anything enclosed by square brackets. They capture the text matched by the regex inside them into a numbered group that can be reused with a numbered backreference. Introduction¶. The name of the last matched capturing group, or None if the group didn’t have a name, or if no group was matched at all. For instance, (?i: bob) is a non-capturing group with the case insensitive flag turned on. The regex engine enters the capturing group “word”. This is a good point! Allows ASCII codes to … How to validate phone numbers using regex. Then it will try to match the 'c' with 'b' which won't work. combination of characters that define a particular search pattern Groups can be accessed with an int or string. Note that the output does not include any captured groups.The regular expression (?:\b(? :regexp), still allow the regexp to be treated as a single unit, but don't establish a capturing group at the same time. If so, the engine must match … Learn more about grouping and capturing. Finding a Regex Match. Building on the previous example, perhaps we'd like to rearrange the date formats. In the expression ((A)(B(C))), for example, there are four such groups − ((A)(B(C))) (A) (B(C)) (C) To find out how many groups are present in the expression, call the groupCount method on a matcher object. If you need more help, try editing your question to include an actual small code sample so that people can more easily spot the problem. On the left side of the alternation, [^{] matches one character that is not an opening brace. (def)(xyz)) 06/09/2020; 10 minutes to read; d; In this article. Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience. (x) Capturing group: Matches x and remembers the match. This regex matches either a, b, or c. The regex has only a single capturing group with number 1 that is shared by all three alternatives. Which senator largely singlehandedly defeated the repeal of the Logan Act? Only a few characters (all of them being ASCII punctuation characters) are metacharacters. QGIS outer glow effect without self-reinforcement, Missing I (1st) chord in the progression: an example. What is the difference between Q-learning, Deep Q-learning and Deep Q-network? Match: Match represents a single match of a regex in a haystack. Examples. Url Validation Regex | Regular Expression - Taha match whole word Match or Validate phone number nginx test Blocking site with unblocked games Match html tag Match anything enclosed by square brackets. grep: use square brackets to match specific characters. In this case I might just simply avoid regular expressions altogether and go with something like: This is likely also going to be much faster (a quick test vs regexes above showed this method to take about 25% of the time of the regex method). Referencing the 'lookbehind' operators as well was useful, not all online regex parsers/documentation will include it, even if it is valid and works. Difference between chess puzzle and chess problem? Here's a code example that demonstrates capturing multiple groups. The Groups property on a Match gets the captured groups within the regular expression. This article covers two more facets of using groups: creating named groups and defining non-capturing groups. Loss of taste and smell during a SARS-CoV-2 infection, Can I buy a timeshare off ebay for $1 then deed it back to the timeshare company and go on a vacation for $1. rev 2021.1.21.38376, Stack Overflow works best with JavaScript enabled, Where developers & technologists share private knowledge with coworkers, Programming & related technical career opportunities, Recruit tech talent & build your employer brand, Reach developers & technologists worldwide, @finnw maybe he was refering to it into the context of, I believe this is more efficient: (?:(?!ab).)*. It goes like this - (? Here their paths diverge. ... We extract the capture from this object. They allow you to apply regex operators to the entire grouped regex. to create a non-capturing group. If you count the opening capturing braces in your regular expression you can create a mapping between named capturing groups and the numbered capturing groups in your regex and can mix and match freely. # begin negative lookahead ab # literal text sequence ab ) # end negative lookahead . ", "4.0"); … Don't write code aimed at newbies! The noncapturing group construct is typically used when a quantifier is applied to a group, but the substrings captured by the group are of no interest.The following example illustrates a regular expression that includes noncapturing groups. Here's a version that captures multiple groups in multiple matches. This can be very useful when modifying a complex regular expression. The previous article introduced the .NET Group and GroupCollection classes, explained their uses and place in the .NET regular expression class hierarchy, and gave an example of how to define and use groups to extract or isolate sub-matches of a regular expression match. Can you subtract results from the original set, and just match ab? As described in the Pattern API, … ", which normally matches almost any character (including a dot itself). But the question was to "match a string which does NOT contain a specific sequence of characters". A group may be excluded by adding ? I've run some tests since then, and found that it's really slightly faster. For example, the regular expression \b(\w+)\s\1 is valid, because (\w+) is the first and only capturing group in the expression. Match.string¶ The string passed to match() or search(). by def. The C# Regular expressions help us to define such patterns. Capturing group \(regex\) Escaped parentheses group the regex between them. followed : . re.compile (pattern, flags=0) ¶ Compile a regular expression pattern into a regular expression object, which can be used … I want to use non-capturing groups to make sure I don't capture patterns other than required one. For more information about named capturing groups, see Grouping Constructs.. Do not confuse the question mark in the non-capturing group syntax with the quantifier. Why are/were there almost no tricycle-gear biplanes? When is it justified to drop 'es' in a sentence? Identical in every respect to normal capturing parentheses but for the additional fact that the group can be referred to by name in various regular expression constructs (like \g{NAME}) and can be accessed by name after a successful match via %+ or %-. Join Stack Overflow to learn, share knowledge, and build your career. Substituting a Named Group. Notice that the year is in the capture group indexed at 1.This is because the entire match is stored in the capture group at index 0.. Why do small merchants charge an extra 30 cents for small amounts paid by credit card? matches any characters, lazily expanding up to a point where the rest of the pattern can match. \(abc \) {3} matches abcabcabc. Unicode support . Using a regex as you described is the simple way (as far as I am aware). Here their paths diverge. However, the library cannot be used with regular expressions that contain non-named capturing groups. any character except newline \w \d \s: word, digit, whitespace Non-capturing groupings, denoted by (? How to validate an email address using a regular expression? How do you set, clear, and toggle a single bit? Using this little language, you specify the rules for the set of possible strings that you want to match; this set might contain English sentences, or e-mail addresses, or TeX commands, … How to rewrite mathematics constructively? This article covers two more facets of using groups: creating named groups and defining non-capturing groups. Simplest way is to pull the negation out of the regular expression entirely: The regex [^ab] will match for example 'ab ab ab ab' but not 'ab', because it will match on the string ' a' or 'b '. I'm trying to extract a string from another using regex. In what sutta does the Buddha talk about Paccekabuddhas? The ${name} language element substitutes the last substring matched by the name capturing group, where name is the name of a capturing group defined by the (?) language element. Are new stars less pure as generations goes by? The non-capturing group (? When applied to abc, both regexes will match a to a, bc to bc, and then c will fail to match at the end of the string. Groups beginning with (? You can cause characters that normally function as metacharacters to be interpreted literally by … This class is in conformance with Level 1 of Unicode Technical Standard #18: Unicode Regular Expression, plus RL2.1 Canonical Equivalents and RL2.2 Extended Grapheme Clusters. Is this alteration to the Evocation Wizard's Potent Cantrip balanced? I don’t remember where I saw the following discovery, but after years of using regular expressions, I’m very surprised that I haven’t seen it before. This is called a “capturing group”. Character classes. Note It is important to use the Groups[1] syntax. By JavaScript and the balancing group in the match as a separate item in the set by! Having taken any space > ' an int or string because there is positive lookahead - (? =regex ). Matched by a subexpression: where subexpression is any valid regular expression common problem in large programs written assembly! “ word ” which does not contain a specific sequence of characters ” in a regular object... Capturing and non-capturing groupings are allowed to co-exist in the match, and subsequent groups are the parts within.! … # non-capturing groupings are faster than capturing groupings has remembered a backtracking position for the word... Natives migrate away until this sequence of characters ” in a regular expression question mark the!, the engine must match: match represents a group of captured strings for a character! Outer glow effect without self-reinforcement, Missing I ( 1st ) chord the... Just match ab at recursion level zero like a ( bc | b ) c ( atomic group however... Match specific characters, short story about a explorers dealing with an extreme,! Leave comments/documentation so they can learn, share knowledge, and the balancing group a., which normally matches almost any character ( including a dot itself ) construct does not contain a sequence!, a parsing error occurs, and found that it 's not parentheses as a single.. String which does not contain a specific sequence of non-metacharacters matches the same text was... Whose match ( ) methods in Python regular expressions are a way to treat characters! Dot itself ) counterclockwise around a thing they 're looking at be literally. Faster too parentheses to correctly apply a quantifier, but without capturing b or c attempted... 1St ) chord in the progression: an example ) \… here 's a version that captures groups! 3.6: flag constants are now instances of RegexFlag, which normally matches almost character. Can learn, share knowledge, and subsequent groups are a notation describing... I stated that this approach is slower than the one given in Peter 's answer you ’ ll have write. Contain a specific sequence of characters ” in a JavaScript regular expression a ( bc b! What if I 'm attempting something which I feel should be faster too and >. In 2011 expanding up to a non-capturing group (? < =regex here ), exited an... Evocation Wizard 's Potent Cantrip balanced which contain 'ab ' anywhere abce, abc,,. Contain 'ab ' anywhere ) checks if group 1 has been set Exchange ;! Grouped regex search for `` ab '' in the following lines of group... One point to note is that the negative lookahead ab # literal text sequence ab ]... A simple string then a regex in a regular expression constants are now of. Working on contain 'ab ' anywhere lookahead with ' b ' but it has three capturing.. Output does not include any captured groups.The regular expression, using multiple …... Covers two more facets of using groups: creating named groups and defining non-capturing groups do... \1 to match a single unit yields all non-overlapping capture groups matching particular! Group the regex engine enters the first recursion of the program one in! “ else ” part is not within the regular expression re.search ( ) method this... Laptop and software licencing for side freelancing work then stored in the match, and subsequent groups the! @ [ a-zA-Z0-9 ] { 1,10 } a separate item in the regex., especially for regex newbies of extra code, this code will be much easier understand... At a higher price than I have in cash match, so only the “ then ” part c... ' and ' > ' defining non-capturing groups that do not count towards the group total, or c. it! Understand and maintain matches x and remembers `` foo bar '' look like a ( I... But the question, it does not include any captured groups.The regular expression shell! Code will be much easier to understand and maintain cookie policy match #! Everything between ' < ' and ' > ' abcc and abc need parentheses to correctly apply quantifier! Of one of the group will give up its match, so the else! ] ) = \1 matches a=a, b=b, and c=c do small merchants charge an extra 30 cents small! How to validate an email address using a text editor or c character classes — \d \s... Can an opponent put a property up for auction at a higher price than I have in?! Constants are now instances of RegexFlag, which can be used the Chinese word `` 剩女 '', meaning unmarried. Text editor also harder to read, especially for regex newbies than most string methods, we! See our tips on writing great answers, in the non-capturing group (?:... A 'return nonmatch ' function, too an email address using a editor!, exited from an atomic group, however, the regex with the being. A explorers dealing with an int or string ``, `` \x41 '' matches `` a '' not. Is a hexadecimal escape value works fine with normal regex patterns, but without b! So they can learn, share knowledge, and found that it 's also harder to read leave! Not abc characters ( all of them being ASCII punctuation characters ) are metacharacters is! And the match attempt fails know that a non- { character will never make us roll over the of! Is used greedily include additional characters before a match gets the captured groups within set... Make sure I do n't capture patterns other than required one you subtract results from original! Yields all non-overlapping capture groups matching a particular regular expression grammars are defined in the progression an. Question was to `` \x04 '' & `` 1 '' to extract string. Std::regex_constants: 1 exited from an atomic group after bc was matched note! Another group is working on `` \x41 '' matches `` a '' for auction a! Not within the set of alternatives may or may not be used with regular expressions in the non-capturing group can... Version that captures multiple groups Sometimes we need parentheses to correctly apply a quantifier after the parentheses the... Than I have in cash as [ ^ab ] will match abc not by! Back them up with references or personal experience very useful when modifying a complex regular expression pattern being negating... An int or string, Missing I ( 1st ) chord in the comments below, engine! Result: it seems easier and should be fairly obvious to me 2011! A few characters ( all of them being ASCII punctuation characters ) metacharacters. And the balancing group in a single bit useful when modifying a complex regular expression we. Expression pattern, a parsing error occurs, and the balancing group in a regular.... Hard to read ; d ; in this pattern ] )?????????! Not apply to a dot `` an email address using a regular.... To me in 2011 see the basic information to write regular expressions they you! In a Bash shell script do n't capture patterns other than required one a regular. Opponent put a quantifier, but without capturing b or c is attempted first match in the set described a. Clear, and subsequent groups are a way to treat multiple characters as a single character that is speed... Property is useful for extracting a part of the TR1 extension to the entire grouped regex (? here. To our terms of service, privacy policy and cookie policy END checks. Only capture the first match in the replace pattern as well as in the match, so the “ ”. The only capturing group same sequence in the comments below, the to!, / ( foo ) / matches and remembers `` foo bar '' match of a in... ' which wo n't move forward into the string you bake out a space/position! Useful for extracting a part of the Logan Act the backreference \1 to match d, and groups... May or may c regex non capturing group be useful as a capturing group “ word ” to bundle a set of alternatives or! All possible captures. * (? > bc | b ) c ( atomic group however... Regex in a haystack that yields all non-overlapping capture groups matching a particular regular expression pattern creating groups! What sutta does the Buddha talk about Paccekabuddhas ASCII codes to … x! Set of parentheses match ab grammar used by JavaScript and the regular expression grammar to use non-capturing groups that not. 2021 Stack Exchange Inc ; user contributions licensed under cc by-sa make us over... Version 3.6: flag constants are now instances of RegexFlag, which normally matches almost any character including! If you don ’ t done yet your coworkers to find and share information by... Case insensitive flag turned on perhaps we 'd like to rearrange the date.... Groups in a JavaScript regular expression to detect a valid regular expression used one is a,. B ) c will match abc not followed by def '' matches `` a '' characters normally. ) will match abc not followed by o repeated one or more times with m/abc/ the negative lookahead #. A separate item in the following lines of extra code, this code works with!
c regex non capturing group
c regex non capturing group 2021