3

I need a regex which return specific character with a decimal number up to 1 place

I have string text

(AvgC20.1 > 980000) && (C1>C2) MaxC20 MinC20.14

after applying regex get the following result

AvgC20, MaxC20, MinC20

This is the regex I am using

(Avg|Max|Min)[OHLVC]\d+

which return what I want but not return the decimal number up to one place

but I need result like this

AvgC20.1, MaxC20, MinC20.1
Haseeb Khan
  • 930
  • 3
  • 19
  • 41

1 Answers1

4

Add an optional (?:\.\d+)? matching 1 or 0 occurrences of a . followed with 1 or more digits:

(?:Avg|Max|Min)[OHLVC]\d+(?:\.\d+)?
                         ^^^^^^^^^^

See the regex demo

enter image description here

The (?:...)? is an optional non-capturing group. It is optional (=matches one or zero occurrences) due to the ? quantifier (a greedy one, that is why I mention one or zero, not zero or one). The non-capturing group is used for grouping purposes, without creating a buffer for the captured value in the memory. I suggested using the non-capturing group because the final result should be equal to the whole match value, so, no need tracking and storing those subvalues.

NOTE on the non/capturing groups in .NET: In .NET code, you can actually use numbered capturing groups and make them non-capturing by using the RegexOptions.ExplicitCapture flag. Then, memory buffers will get created only for named capturing groups (like (?<gr1>...)).

Pattern details:

  • (?:Avg|Max|Min) - Either Avg, Max or Min
  • [OHLVC] - one uppercase letter from the set
  • \d+ - 1 or more digits
  • (?:\.\d+)? - an optional sequence of a . followed with 1 or more digits.

Sidenote: it is best practice to disallow branches of the same alternation group to match at one and the same location, and (?:Avg|Max|Min) is better written as (?:Avg|M(?:ax|in)). However, what is good for the machine is not that fine for a human eye, so due to readability reasons, I'd advise to keep the first group as is.

C# demo (note that the RegexOptions.ExplicitCapture is passed with the help of the inline (?n) option):

var s = "(AvgC20.1 > 980000) && (C1>C2) MaxC20 MinC20.14";
var pattern = @"(?n)(Avg|Max|Min)[OHLVC]\d+(\.\d+)?";
var result = Regex.Matches(s, pattern)
        .Cast<Match>()
        .Select(p => p.Value)
        .ToList();
foreach (var r in result) // Demo printing the results
    Console.WriteLine(r);
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Perhaps you should explain why `?:` is needed. Beginners won't know that parentheses are more than just a way to group characters – Panagiotis Kanavos Sep 28 '16 at 09:48
  • \d+ should be \d? – jdweng Sep 28 '16 at 09:54
  • @HaseebKhan: You mean that uppercase letter is optional? Add a `?` after it. See [`(?:Avg|Max|Min)[OHLVC]?\d+(?:\.\d+)?`](http://regexstorm.net/tester?p=(%3f%3aAvg%7cMax%7cMin)%5bOHLVC%5d%3f%5cd%2b(%3f%3a%5c.%5cd%2b)%3f&i=(AvgC20+%3e+980000)+%26%26+(C1%3eC2)+MaxC20+MinC20.14+Min40.1) – Wiktor Stribiżew Sep 28 '16 at 09:58
  • @Wiktor Stribiżew how to extract number after decimal only using regex. I have a number like 40.2 I just need to extract 2 using regex – Haseeb Khan Sep 28 '16 at 12:38
  • See http://ideone.com/xZfdv7, use additional group, e.g. `@"(?n)(Avg|Max|Min)[OHLVC]\d+(\.(?\d+))?"` – Wiktor Stribiżew Sep 28 '16 at 12:43
  • @WiktorStribiżew can you tell me how to extract only integer number (non decimal ) from a string.I have a string like (778.25 -85.63) > 45000 after applying regex I just need 45000. what's the appropriate regex for that? – Haseeb Khan Oct 04 '16 at 10:14
  • Use `@"(?<!\.)\d+(?!\.\d)"` – Wiktor Stribiżew Oct 04 '16 at 10:16
  • @WiktorStribiżew check here its not matching integer only also capturing decimal number. http://regexstorm.net/tester?p=(%3f%3c!%5c.)%5cd%2b(%3f!%5c.%5cd)&i=(778.25+-85.63)+%3e+45000 – Haseeb Khan Oct 04 '16 at 10:20
  • Yes, add word boundaries - `(?<!\.)\b\d+\b(?!\.\d)` – Wiktor Stribiżew Oct 04 '16 at 10:23
  • @Wiktor Stribiżew this is a regex which is used to select only constant number like 5,6,100. How can I include positive and negative sign +/-. @"(?<!\.)\b\d+\b(?!\.\d)" I need to select negative and positive number with sign as well +100, -100, -50 +78 – Haseeb Khan Oct 26 '16 at 14:43
  • Add them - `(?<!\.)[-+]?\b\d+\b(?!\.\d)` – Wiktor Stribiżew Oct 26 '16 at 14:45
  • Thank you very much for such prompt response. – Haseeb Khan Oct 26 '16 at 15:11