1. Introduction to Alternation in Regex
2. The Basics of VBA and Its Regex Capabilities
3. Understanding the Alternation Operator in Regex
4. Practical Examples of Alternation in VBA Regex
5. Advanced Alternation Techniques for Complex Patterns
6. Performance Considerations When Using Alternation
7. Common Pitfalls and How to Avoid Them
Alternation in regular expressions (regex) is a powerful feature that allows for the matching of one out of several possible sequences within a string. It's akin to having multiple paths in a maze and being able to choose which one to follow. In the context of VBA (Visual Basic for Applications), alternation can be particularly useful due to the language's focus on automating tasks in Microsoft Office applications. By harnessing the power of alternation, users can create more flexible and dynamic search patterns, making their scripts more efficient and their data manipulation more sophisticated.
From a technical standpoint, alternation is represented by the pipe symbol (`|`) in regex. This symbol serves as a logical OR operator between multiple expressions, allowing the regex engine to match any one of the expressions listed. Here's an in-depth look at how alternation can be utilized in VBA regex:
1. Basic Alternation: At its simplest, alternation can be used to match one word or another. For example, the regex pattern `apple|banana` will match either "apple" or "banana" in a given string.
2. Grouping with Parentheses: To alternate between more complex patterns, parentheses are used to group parts of the regex. For instance, `(apple|banana) pie` will match "apple pie" or "banana pie".
3. Combining with Other Regex Features: Alternation becomes even more powerful when combined with other regex constructs. For example, `^(apple|banana|cherry)$` will match any string that is exactly "apple", "banana", or "cherry", with `^` and `$` denoting the start and end of the string, respectively.
4. Nested Alternation: You can nest alternation within other alternation groups for more complex patterns. For example, `((green|red) apple|banana)` will match "green apple", "red apple", or "banana".
5. Efficiency Considerations: The order of alternated patterns can affect the performance of the regex. It's generally more efficient to place the most likely pattern first.
Here are some examples to illustrate these points:
- Example 1: Matching a simple choice.
```regex
Apple|banana
```This pattern will match "apple" or "banana" in a text like "I like apple and banana."
- Example 2: Grouping alternatives.
```regex
(apple|banana) pie
```This will match "apple pie" or "banana pie" in "We have apple pie and banana pie on the menu."
- Example 3: Using anchors with alternation.
```regex
^(apple|banana|cherry)$
```This pattern will only match strings that are exactly "apple", "banana", or "cherry", nothing more, nothing less.
Alternation is a testament to the flexibility and expressive power of regex. It allows users to succinctly represent multiple possibilities within a single pattern, making it an indispensable tool in text processing and data manipulation tasks. Whether you're a beginner or an experienced VBA programmer, understanding and utilizing alternation in regex can greatly enhance your scripting capabilities.
Introduction to Alternation in Regex - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
visual Basic for applications (VBA) is a powerful scripting language that enables automation within the Microsoft Office suite. It's particularly adept at handling tasks that involve repetitive actions or complex calculations. One of the lesser-known, yet incredibly potent features of VBA is its ability to work with regular expressions (regex). Regex in VBA allows users to search, match, and manipulate strings with a precision that standard string functions can't match. This capability opens up a plethora of possibilities for data parsing, validation, and formatting.
From a developer's perspective, the integration of regex into VBA is a game-changer. It means that complex string patterns can be identified and manipulated without the need for lengthy and convoluted code. For example, consider the task of extracting phone numbers from a document. With regex, this can be achieved with a simple pattern like `"\(\d{3}\) \d{3}-\d{4}"`, which matches the common North American phone number format.
Here's an in-depth look at how VBA leverages regex capabilities:
1. Enabling Regex in VBA: Before you can use regex in VBA, you need to enable the Microsoft VBScript Regular Expressions library. This is done through the VBA editor by going to Tools -> References and checking the appropriate box.
2. Creating a Regex Object: Once enabled, you can create a regex object in VBA using `Dim regex As New RegExp`.
3. Setting Regex Properties: The regex object has several properties that control its behavior. The `.Pattern` property is where you define the regex pattern, `.IgnoreCase` determines case sensitivity, and `.Global` controls whether to find one match or all matches.
4. Executing Regex Methods: The two primary methods are `.Test` and `.Execute`. `.Test` returns a Boolean indicating if the pattern matches the string, while `.Execute` returns a MatchCollection object containing all the matches.
5. Working with Matches: Each item in the MatchCollection has properties like `.Value` for the matched string and `.Index` for the position in the input string. You can iterate through the collection to work with each match.
6. Using Regex Patterns: VBA supports most standard regex patterns, such as character classes, quantifiers, and anchors. For instance, to find words that start with 'a' and end with 'e', you could use the pattern `"a\w*e"`.
7. Substitution and Replacement: VBA's regex can also perform substitutions using the `.Replace` method. This is useful for replacing text in a string based on a pattern.
Here's an example of regex in action within VBA:
```vba
Sub UseRegex()
Dim regex As New RegExp
Dim matches As MatchCollection
Dim match As Match
' Define the pattern for a simple email address
Regex.Pattern = "[\w.-]+@[\w.-]+\.[A-Za-z]{2,}"
Regex.Global = True
' Test the pattern against a sample string
Set matches = regex.Execute("Please contact us at info@example.com or support@example.net.")
' Output each found email address
For Each match In matches
Debug.Print match.Value
Next match
End Sub
In this example, the regex object is used to find all email addresses in a given string. The pattern `[\w.-]+@[\w.-]+\.[A-Za-z]{2,}` is designed to match a typical email format, and the `Global` property ensures that all occurrences are found. The `Execute` method returns a collection of matches, which is then iterated over to print out each email address.
Understanding and utilizing regex within VBA can significantly enhance a developer's ability to work with strings. It's a skill that, once mastered, can save time and simplify many common programming tasks. Whether you're formatting data, validating input, or searching for specific patterns, regex is an invaluable tool in the VBA toolkit.
The Basics of VBA and Its Regex Capabilities - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
The alternation operator in regular expressions, often represented by the vertical bar `|`, serves as a powerful tool for matching one of many expressions. It's akin to a logical OR in programming, where it allows the regex engine to search for multiple patterns in a single pass. This operator can be particularly useful when you're dealing with variations in text patterns that you want to match. For instance, if you're parsing a document for mentions of various programming languages, you might use a regex like `Java|Python|C#` to find any occurrence of these three.
From a performance standpoint, the alternation operator can be both a blessing and a curse. On one hand, it simplifies the pattern and can make your regex more readable. On the other hand, if not used carefully, it can lead to inefficient backtracking, especially if the alternatives have a lot of overlap or are not ordered optimally.
Let's delve deeper into the nuances of the alternation operator with a numbered list:
1. Order Matters: The regex engine evaluates alternatives from left to right, stopping at the first match. Therefore, ordering your alternatives from most to least likely can improve performance. For example, if you're searching for keywords in a VBA-related text, placing `VBA` before less common terms can be more efficient.
2. Non-Capturing Groups: To avoid unnecessary capturing of groups, which can slow down your regex, use non-capturing groups with `?:`. For example, `(?:Java|Python|C#)` will match any of the three languages without capturing them.
3. Avoiding Redundancy: Redundant patterns within alternation can cause the regex engine to do extra work. For instance, `set|settle` has an overlap. Instead, factor out the common part: `set(?:tle)?`.
4. Complex Alternations: When dealing with complex patterns, consider breaking them into smaller, manageable pieces. This can make your regex more readable and maintainable.
5. Nested Alternations: You can nest alternation operators within groups to create a hierarchy of choices. For example, `(Java(Script)?|Python|C#)` matches `Java`, `JavaScript`, `Python`, or `C#`.
Here's an example to illustrate the use of the alternation operator in a VBA regex scenario:
```vba
Function FindProgrammingLanguage(text As String) As String
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Global = True
.Pattern = "Java(Script)?|Python|C#"
End With
If regex.Test(text) Then
FindProgrammingLanguage = regex.Execute(text)(0)
Else
FindProgrammingLanguage = "No match found"
End If
End Function
In this function, we're looking for any mention of `Java`, `JavaScript`, `Python`, or `C#` in a given string. The alternation operator allows us to check for all these languages with a single pattern, showcasing its utility in creating concise and effective regexes. The use of a non-capturing group for `JavaScript` ensures that we match the whole word without the overhead of capturing a group we don't need. This is just one example of how the alternation operator can be employed to make your regex patterns more efficient and your code cleaner.
Understanding the Alternation Operator in Regex - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
Alternation in VBA Regex is a powerful concept that allows a single regular expression to match multiple potential sequences of characters. It's akin to having multiple search patterns within the same query, providing a versatile tool for string matching and data validation. This feature is particularly useful in scenarios where a string might follow one of several patterns, or when you want to search for multiple terms simultaneously. By using the vertical bar (|) symbol, VBA developers can separate alternatives within a pattern, effectively telling the regex engine to match any one of the separated sequences. This not only simplifies the code but also enhances its efficiency and readability.
Let's delve into some practical examples to understand how alternation can be applied in real-world VBA scenarios:
1. Matching Multiple Formats: Suppose you're working with data that contains phone numbers in various formats. You might encounter numbers like "123-456-7890", "(123) 456-7890", or "123.456.7890". Using alternation, you can create a regex pattern that matches all these formats:
```vba
Dim pattern As String
Pattern = "(\d{3}-|\(\d{3}\)\s?|\d{3}\.)\d{3}-\d{4}"
```This pattern will match any of the three formats, allowing for dashes, spaces, parentheses, or dots.
2. Identifying Keywords: If you need to search for specific keywords within a text, alternation can help. For example, if you're looking for the words "excel", "access", or "word" in a body of text, the pattern would be:
```vba
Dim pattern As String
Pattern = "excel|access|word"
```This simple pattern is much more efficient than writing separate expressions for each keyword.
3. Flexible Date Formats: Dates can come in numerous formats, and alternation can assist in recognizing them. Whether the date is in "MM/DD/YYYY", "MM-DD-YYYY", or "DD/MM/YYYY" format, a single regex can handle it:
```vba
Dim pattern As String
Pattern = "(\d{2}/\d{2}/\d{4}|\d{2}-\d{2}-\d{4}|\d{2}/\d{2}/\d{4})"
```This pattern uses alternation to match any of the three common date formats.
4. Handling Variations in Spelling: Words like "color" and "colour" can be matched using alternation to account for different spellings:
```vba
Dim pattern As String
Pattern = "colou?r"
```The question mark makes the "u" optional, effectively matching both American and British spellings.
5. Complex Patterns with Alternation: Sometimes, you may need to match complex patterns that have multiple variations. For instance, matching a URL pattern could involve different protocols and subdomains. A simplified version of such a pattern might look like this:
```vba
Dim pattern As String
Pattern = "(http|https|ftp)://(www\.)?.+\.(com|net|org)"
```This pattern matches different protocols, optional "www", and various domain extensions.
Alternation in VBA Regex opens up a multitude of possibilities for pattern matching. It allows for more concise and flexible expressions, which can be incredibly beneficial when dealing with diverse datasets or when the input data might vary in format. By mastering alternation, VBA developers can write more efficient and adaptable code, making their applications more robust and user-friendly. Remember, while alternation is a potent tool, it's also important to use it judiciously to maintain the performance of your regex queries.
Practical Examples of Alternation in VBA Regex - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
In the realm of regular expressions, alternation stands as a powerful tool, allowing patterns to match one thing or another, effectively broadening the scope of possibilities. Advanced alternation techniques, particularly in VBA Regex, elevate this capability, enabling the matching of complex patterns with greater precision and efficiency. These techniques are not just about using the vertical bar (`|`) to separate alternatives; they involve strategic thinking and pattern design to ensure that the regex engine can navigate through the myriad of possibilities in the most optimized way.
From a performance standpoint, poorly designed alternations can lead to excessive backtracking, which can significantly slow down the regex engine. Therefore, understanding how to construct alternations for complex patterns is crucial. Here, we delve into advanced strategies that can be employed to enhance the effectiveness of alternation in regex, especially within the context of VBA.
1. Non-Capturing Groups: Utilize non-capturing groups `(?:...)` when you don't need to save the matched substrings. This reduces memory overhead and speeds up the matching process.
2. Atomic Grouping: Implement atomic grouping `(?>...)` to prevent the regex engine from backtracking into the group once it has successfully matched, thus avoiding unnecessary processing time.
3. Lookahead and Lookbehind Assertions: Use lookahead `(?=...)` and lookbehind `(?<=...)` assertions to assert certain conditions without consuming characters, allowing for more complex alternations without affecting the surrounding text.
4. Balancing Groups: In VBA Regex, balancing groups `(?
5. Conditional Alternation: Employ conditional alternation `(?(condition)yes-pattern|no-pattern)` to apply different patterns based on the presence or absence of a certain condition, which is particularly useful in scenarios with optional elements.
Let's illustrate these concepts with an example. Suppose we want to match a date format that can either be `MM/DD/YYYY` or `YYYY-MM-DD`. Here's how we might apply advanced alternation techniques:
```vba
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Pattern = "(?:\d{2}\/\d{2}\/\d{4})|(?:\d{4}-\d{2}-\d{2})"
.Global = True
End With
Dim matches As Object
Set matches = regex.Execute("Today's date is 04/07/2024 and tomorrow will be 2024-04-08.")
If matches.Count > 0 Then
MsgBox "Match found: " & matches(0).Value
Else
MsgBox "No match found."
End If
In this code, we use a non-capturing group to match either of the date formats without saving the substrings, which makes the regex more efficient. By understanding and applying these advanced alternation techniques, one can craft complex regex patterns that are not only functional but also optimized for performance in VBA environments. <|\im_end|>
Remember, these techniques are not exhaustive, and the complexity of patterns will often dictate the need for a combination of these strategies to achieve the desired matching behavior. The key is to experiment and refine your regex patterns to ensure they are as efficient and effective as possible.
Advanced Alternation Techniques for Complex Patterns - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
Alternation in regular expressions is a powerful feature that allows for the matching of one out of several possible sequences. It's akin to saying, "match this or that." In VBA Regex, alternation is denoted by the vertical bar `|` symbol. While this feature can greatly enhance the flexibility of your regex patterns, it also comes with performance implications that are crucial to understand. When a regex engine processes an alternation, it attempts to match each alternative in the order they are provided. This means that the efficiency of your pattern can be significantly affected by the order and complexity of the alternatives. Poorly designed alternation can lead to excessive backtracking, which can slow down the matching process considerably, especially with large data sets or complex patterns.
From a performance standpoint, consider the following insights:
1. Order of Alternatives: Place the most likely alternative first. If you're matching words in a text and you know that "apple" is more frequent than "apricot", order your alternation as `apple|apricot` to ensure the engine matches "apple" quickly without unnecessary checks for "apricot".
2. Non-Capturing Groups: Use non-capturing groups `(?:...)` for alternation when you don't need to capture the matched text. This reduces the overhead of storing captured groups.
3. Atomic Grouping: To prevent the regex engine from wasting time on needless backtracking, use atomic groups `(?>...)`. For example, `(?>apple|apricot)` will not backtrack within the group to try another alternative if a larger pattern fails.
4. Common Prefixes: Factor out common prefixes to reduce the amount of work the regex engine must do. Instead of `apple|apricot`, use `a(?:pple|pricot)`.
5. Avoiding Overlapping Matches: Ensure that your alternation patterns do not overlap in a way that causes the engine to check the same possibility multiple times. For instance, `apple|applepie|pie` has overlapping patterns that can be optimized.
6. Specificity: Be as specific as possible with your alternation. Broad or vague patterns can match more than intended, causing performance issues.
7. Testing with Real Data: Always test your regex patterns with data that is representative of the actual use case to ensure that performance is acceptable.
8. Profiling Tools: Utilize profiling tools to measure the performance of your regex and make adjustments as necessary.
Let's illustrate some of these points with examples:
- Example 1: Order of Alternatives
Suppose you have a list of fruit names, and you want to match either "apple" or "apricot". If "apple" occurs more frequently, your alternation should be `apple|apricot` rather than `apricot|apple`.
- Example 2: Common Prefixes
If you're matching "apple" or "apricot", instead of writing `apple|apricot`, you can optimize the pattern to `a(?:pple|pricot)`.
By considering these performance considerations, you can write more efficient VBA Regex patterns that make better use of alternation, leading to faster and more reliable code execution.
Performance Considerations When Using Alternation - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
When working with regular expressions in vba, particularly with the alternation operator, it's easy to fall into traps that can lead to unexpected results or inefficient code. Alternation, denoted by the pipe symbol `|`, allows you to match one of several patterns; however, its misuse can cause a host of issues. From the perspective of a seasoned developer, the most common pitfalls include overusing alternation when simpler constructs could suffice, misunderstanding the precedence rules leading to incorrect matches, and neglecting the performance implications of complex alternations.
To navigate these challenges, it's essential to adopt a strategic approach. Here are some insights and in-depth information on how to avoid common pitfalls:
1. Overuse of Alternation:
- Example: Using `cat|dog|fish` to match any of the three pet types in a string.
- Pitfall: This can be inefficient, especially with longer lists.
- Solution: If the alternatives share a common prefix or suffix, use grouping to simplify the regex. For instance, `ca(t|rp|nine)` is more efficient than `cat|carp|canine`.
2. Misunderstanding Precedence:
- Example: The pattern `cat|dog house` will match `cat` or `dog house`, not `cat house` or `dog house`.
- Pitfall: Assuming alternation has lower precedence than concatenation.
- Solution: Use parentheses to enforce the desired precedence: `(cat|dog) house`.
3. Performance Issues:
- Example: `(cat|caterpillar)` can cause backtracking, especially if the subject string contains many instances of `cat` not followed by `erpillar`.
- Pitfall: Not considering the regex engine's backtracking.
- Solution: Optimize by structuring alternatives to minimize backtracking, such as `caterpillar|cat`.
4. Capturing Groups vs. Non-Capturing Groups:
- Example: Using `(cat|dog)` when you don't need to capture the match.
- Pitfall: Unnecessary capturing can slow down the regex engine.
- Solution: Use non-capturing groups `(?:cat|dog)` when you don't need to capture the match.
5. Complex Alternations:
- Example: `cat|dog|mouse|elephant` to match various animals.
- Pitfall: Long alternation lists can become hard to read and maintain.
- Solution: Consider using character classes or other constructs when appropriate, or break the regex into multiple simpler expressions.
By being mindful of these pitfalls and applying the solutions provided, you can write more efficient and maintainable VBA regex patterns. Remember, regular expressions are a powerful tool, but with great power comes great responsibility. Use alternation wisely to ensure your code remains clear and efficient.
Common Pitfalls and How to Avoid Them - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
Testing and debugging are critical steps in the development of any code, including the use of regular expressions (regex) in Visual Basic for Applications (VBA). When it comes to regex, alternation is a powerful feature that allows you to match one out of several possible sequences. It's akin to saying, "match this or that." In VBA, this is achieved using the pipe symbol (`|`). However, the convenience of alternation comes with its own set of challenges. It can introduce complexity and unexpected behavior if not handled with care. Therefore, testing and debugging become even more important to ensure that your regex patterns do exactly what you intend them to do.
Here are some in-depth insights into testing and debugging alternation in VBA regex:
1. Understand the Order of Precedence: In regex, alternation has a lower precedence than concatenation, which means `A|BC` is interpreted as "match A or match BC." This can lead to unexpected matches if not properly understood. For example, the pattern `hello|world` will match "hello" in "hello there" and "world" in "otherworldly," but not "hello world" in its entirety.
2. Use Non-Capturing Groups for Clarity: When using alternation, it's often helpful to group alternatives using non-capturing groups to avoid unintended capturing of matched text. For instance, `(?:apple|banana)` will match either "apple" or "banana" without capturing them for back-references.
3. Test Each Alternative Individually: Before combining alternatives into a single pattern, test each one individually. This helps isolate issues and ensures that each part of the alternation works as expected.
4. Be Wary of Overlapping Matches: Alternatives that can match overlapping text can cause the regex engine to skip potential matches. For example, the pattern `cat|caterpillar` will never match "caterpillar" because "cat" will match first.
5. Use Anchors to Narrow Down Matches: If you're getting too many matches due to the broad nature of alternation, consider using anchors like `^` for the start of a string or `$` for the end. For example, `^(?:cat|dog)$` will only match strings that are exactly "cat" or "dog".
6. Leverage Debugging Tools: Use VBA's built-in debugging tools, such as the Immediate window and Watch window, to test regex patterns and view their matches in real-time.
7. Consider Performance: Alternation can slow down your regex, especially if you have many alternatives or if they're complex. Monitor performance and refactor if necessary.
8. Document Your Regex: Alternation can make regex patterns hard to read. Always document your patterns with comments to explain what each alternative is supposed to match.
Here's an example to highlight the importance of testing:
```vba
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Pattern = "^(?:cat|dog|mouse)$"
.Global = False
.IgnoreCase = True
End With
' Test the regex with different inputs
Dim testStrings(2) As String
TestStrings(0) = "cat"
TestStrings(1) = "dog"
TestStrings(2) = "mouse"
Dim i As Integer
For i = LBound(testStrings) To UBound(testStrings)
Debug.Print "Testing: " & testStrings(i)
Debug.Print "Match: " & regex.Test(testStrings(i))
Next i
In this example, we're testing a regex pattern that uses alternation to match exactly "cat," "dog," or "mouse." By running this code in the VBA environment, you can see how each string is tested against the pattern and whether it matches or not. This kind of testing is invaluable for ensuring that your regex patterns behave as expected when using alternation.
Testing and Debugging Alternation in VBA Regex - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
In the realm of text processing with VBA's Regular Expressions (Regex), alternation is just the tip of the iceberg. While it allows us to match one pattern or another, there are other features that offer even more nuanced control and efficiency. These features enable us to construct patterns that are not only precise but also adaptable to the complex variability of real-world data.
From a developer's perspective, the power of Regex lies in its ability to perform complex text manipulations succinctly. A business analyst might appreciate Regex for its capability to clean and standardize data, while a data scientist could leverage Regex for pre-processing tasks in natural language processing. Each viewpoint underscores the versatility of Regex in different scenarios.
Here are some of the other powerful Regex features in VBA:
1. Lookahead and Lookbehind Assertions: These are zero-width assertions that allow you to match a pattern only if it's followed or preceded by another pattern. For example, `(?<=\d{3})\d{2,}` will match at least two digits that are preceded by exactly three digits.
2. Non-Capturing Groups: Sometimes, you need to group parts of your pattern, but you're not interested in capturing them for later use. Non-capturing groups `(?:...)` allow you to do just that. For instance, `(?:\d{3}-)?\d{3}-\d{4}` matches phone numbers with or without an area code.
3. Backreferences: These allow you to reuse part of the matched text. For example, `(\w+) \1` matches two consecutive identical words by referring back to the first capturing group.
4. Character Classes and Sets: Beyond the basic `\d`, `\w`, and `\s`, you can define your own sets of characters `[aeiou]` to match any vowel, or use a negated set `[^aeiou]` to match anything but a vowel.
5. Greedy vs. Lazy Quantifiers: Greedy quantifiers match as much text as possible, while lazy quantifiers match as little as possible. For example, `.*?` is a lazy quantifier that will match the shortest string possible.
6. Word Boundary `\b`: This asserts a position at the start or end of a word. For instance, `\bword\b` ensures that 'word' is matched as a whole word and not as part of another word like 'swordfish'.
7. Modifiers: Modifiers like `i` for case-insensitive matching or `m` for multi-line matching can change how the pattern is interpreted. For example, `(?i)monday` matches 'Monday', 'monday', or 'MONDAY'.
To illustrate, consider a scenario where you need to extract hashtags from a document. A simple pattern like `#\w+` might suffice, but what if you want to exclude numeric-only hashtags? You could use a negative lookahead assertion: `#(?!\d+\b)\w+`.
Each feature opens up new possibilities for text processing, making VBA's Regex a powerful tool in any programmer's arsenal. By understanding and combining these features, you can tackle even the most challenging text manipulation tasks with confidence.
Other Powerful Regex Features in VBA - Alternation: Exploring Paths of Possibility: Alternation in VBA Regex
Read Other Blogs