Human friendly alternative to Regular Expressions

Overview

test-go test-java test-javascript test-ruby

Cucumber Expressions

Cucumber Expressions is an alternative to Regular Expressions with a more intuitive syntax.

Try Cucumber Expressions in your browser.

Cucumber supports both Cucumber Expressions and Regular Expressions for defining Step Definitions, but you cannot mix Cucumber Expression syntax with Regular Expression syntax in the same expression.

On platforms that don't have a literal syntax for regular expressions (such as Java), Cucumber will create a Cucumber Expression by default. To use Regular Expressions, add anchors (starting with ^ and ending with $) or forward slashes (/). For more information, see Cucumber Expression - Java Heuristics.

Introduction

Let's write a Cucumber Expression that matches the following Gherkin step (the Given keyword has been removed here, as it's not part of the match).

I have 42 cucumbers in my belly

The simplest Cucumber Expression that matches that text would be the text itself, but we can also write a more generic expression, with an int output parameter:

I have {int} cucumbers in my belly

When the text is matched against that expression, the number 42 is extracted from the {int} output parameter and passed as an argument to the step definition.

The following text would not match the expression:

I have 42.5 cucumbers in my belly

This is because 42.5 has a decimal part, and doesn't fit into an int. Let's change the output parameter to float instead:

I have {float} cucumbers in my belly

Now the expression will match the text, and the float 42.5 is extracted.

Parameter types

Text between curly braces reference a parameter type. Cucumber comes with the following built-in parameter types:

Parameter Type Description
{int} Matches integers, for example 71 or -19.
{float} Matches floats, for example 3.6, .8 or -9.2.
{word} Matches words without whitespace, for example banana (but not banana split).
{string} Matches single-quoted or double-quoted strings, for example "banana split" or 'banana split' (but not banana split). Only the text between the quotes will be extracted. The quotes themselves are discarded. Empty pairs of quotes are valid and will be matched and passed to step code as empty strings.
{} anonymous Matches anything (/.*/).

Cucumber-JVM additions

On the JVM, there are additional parameter types for biginteger, bigdecimal, byte, short, long and double.

The anonymous parameter type will be converted to the parameter type of the step definition using an object mapper. Cucumber comes with a built-in object mapper that can handle most basic types. Aside from Enum it supports conversion to BigInteger, BigDecimal, Boolean, Byte, Short, Integer, Long, Float, Double and String.

To automatically convert to other types it is recommended to install an object mapper. See configuration to learn how.

Custom Parameter types

Cucumber Expressions can be extended so they automatically convert output parameters to your own types. Consider this Cucumber Expression:

I have a {color} ball

If we want the {color} output parameter to be converted to a Color object, we can define a custom parameter type in Cucumber's configuration.

The table below explains the various arguments you can pass when defining a parameter type.

Argument Description
name The name the parameter type will be recognised by in output parameters.
regexp A regexp that will match the parameter. May include capture groups.
type The return type of the transformer {{% stepdef-body %}}.
transformer A function or method that transforms the match from the regexp. Must have arity 1 if the regexp doesn't have any capture groups. Otherwise the arity must match the number of capture groups in regexp.
useForSnippets / use_for_snippets Defaults to true. That means this parameter type will be used to generate snippets for undefined steps. If the regexp frequently matches text you don't intend to be used as arguments, disable its use for snippets with false.
preferForRegexpMatch / prefer_for_regexp_match Defaults to false. Set to true if you have step definitions that use regular expressions, and you want this parameter type to take precedence over others during a match.

Java

@ParameterType("red|blue|yellow")  // regexp
public Color color(String color){  // type, name (from method)
    return new Color(color);       // transformer function
}

Kotlin

@ParameterType("red|blue|yellow")   // regexp
fun color(color: String): Color {   // name (from method), type
    return Color(color)             // transformer function
}                                    

Scala

ParameterType("color", "red|blue|yellow") { color: String => // name, regexp
    Color(color)                                             // transformer function, type
}                                    

JavaScript / TypeScript

import { defineParameterType } from 'cucumber'

defineParameterType({
    name: 'color',
    regexp: /red|blue|yellow/,
    transformer: s => new Color(s)
})

The transformer function may return a Promise.

Ruby

ParameterType(
  name:        'color',
  regexp:      /red|blue|yellow/,
  type:        Color,
  transformer: ->(s) { Color.new(s) }
)

Optional text

It's grammatically incorrect to say 1 cucumbers, so we should make the plural s optional. That can be done by surrounding the optional text with parentheses:

I have {int} cucumber(s) in my belly

That expression would match this text:

I have 1 cucumber in my belly

It would also match this text:

I have 42 cucumbers in my belly

In Regular Expressions, parentheses indicate a capture group, but in Cucumber Expressions they mean optional text.

Alternative text

Sometimes you want to relax your language, to make it flow better. For example:

I have {int} cucumber(s) in my belly/stomach

This would match either of those texts:

I have 42 cucumbers in my belly
I have 42 cucumbers in my stomach

Alternative text only works when there is no whitespace between the alternative parts.

Escaping

If you ever need to match () or {} literally, you can escape the opening ( or { with a backslash:

I have {int} \{what} cucumber(s) in my belly \(amazing!)

This expression would match the following examples:

I have 1 {what} cucumber in my belly (amazing!)
I have 42 {what} cucumbers in my belly (amazing!)

You may have to escape the \ character itself with another \, depending on your programming language. For example, in Java, you have to use escape character \ with another backslash.

I have {int} \\{what} cucumber(s) in my belly \\(amazing!)

Then this expression would match the following example:

I have 1 \{what} cucumber in my belly \(amazing!)
I have 42 \{what} cucumbers in my belly \(amazing!)

There is currently no way to escape a / character - it will always be interpreted as alternative text.

Architecture

See ARCHITECTURE.md

Acknowledgements

The Cucumber Expression syntax is inspired by similar expression syntaxes in other BDD tools, such as Turnip, Behat and Behave.

Big thanks to Jonas Nicklas, Konstantin Kudryashov and Jens Engel for implementing those libraries.

The Tiny-Compiler-Parser tutorial by Yehonathan Sharvit inspired the design of the Cucumber expression parser.

Comments
  • Cucumber Expressions for Python

    Cucumber Expressions for Python

    Description

    Cucumber expressions for Python

    Motivation & context

    Fixes #27

    Type of change

    • New feature (non-breaking change which adds new behaviour)

    Checklist:

    • [X] I have read the CONTRIBUTING document.
    • [X] My change needed additional tests
      • [X] I have added tests to cover my changes.
    • [X] My change requires a change to the documentation.
      • [x] I have updated the documentation accordingly.
    • [x] I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.
    opened by jsa34 25
  • Add a release workflow

    Add a release workflow

    Adds an automated release workflow. So far this only works for publishing a Ruby gem, and will need to be extended to publish other language/platform packages.

    See https://github.com/cucumber/common/issues/1688

    Checklist:

    • [x] Generate a new RubyGems API token and add it as RUBYGEMS_API_KEY secret in the Release environment.
    • [x] Generate a new NPM API token and add it as NPM_TOKEN secret in the Release environment.
    • [x] Add Go publishing
    • [x] Add Java publishing
    • [x] Add JavaScript publishing
    • [x] Re-organise things so we have a way to re-run a publish job if it failed.
    • [ ] Factor out our own publish-go action?
    • [x] Factor out our own publish-mvn action?
    opened by mattwynne 19
  • Return the expression source instead of nil

    Return the expression source instead of nil

    🤔 What's changed?

    When running cucumber --format=stepdefs --strict --dry-run we saw plenty of nils where the step definition should have been.

    The to_s method referenced a non-existent instance variable @source instead of the source method.

    🏷️ What kind of change is this?

    • :bug: Bug fix (non-breaking change which fixes a defect)

    📋 Checklist:

    opened by svenwin 10
  • Terraform Compliance v1.3.31, Alternative text bug?

    Terraform Compliance v1.3.31, Alternative text bug?

    👓 What did you see?

    Alternative text fails in this scenario:

    Feature: vm compliance
    
        Scenario: vm Sku compliance
            Given I have azurerm_virtual_machine defined
            Then it must have "vm_size"
            And its value must be Standard_DS1_v2/Standard_DS2_v1
    

    Terminal Output:

    Failure: vm_size property in azurerm_virtual_machine.vm resource does not match with ^Standard_DS1_v2/Standard_DS2_v1$ case insensitive regex. It is set to Standard_DS1_v2.
            And its value must be Standard_DS1_v2/Standard_DS2_v1
              Failure:
    

    ✅ What did you expect to see?

    Scenario to pass.

    📦 Which version are you using?

    Terraform v1.1.7 Terraform Compliance v1.3.31 PowerShell 7.2.1 Win 11 OS, up to date.

    🔬 How could we reproduce it?

    Steps to reproduce the behavior:

    1. Install Terraform Compliance v1.3.31

    2. Extract plan.zip to folder, contains plan file and plan.json and z.feature plan.zip

    3. Run command 'terraform-compliance -p ./plan -f ./' 5.. See error in terminal output.

    🤔 Anything else?

    opened by j4t1nd3r 10
  • Rename module to match github repo

    Rename module to match github repo

    Description

    Recently this repo was extracted from common, this PR changes module name so that it matches new repo and can be discovered by go get.

    Motivation & context

    Fixes go get

    Type of change

    • Bug fix (non-breaking change which fixes an issue)

    Note to other contributors

    No note.

    Update required of cucumber.io/docs

    No update.

    Checklist:

    • [x] My code follows the code style of this project.
    • [ ] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [x] I have read the CONTRIBUTING document.
    • [ ] I have added tests to cover my changes.
    • [x] All new and existing tests passed.
    opened by vearutop 10
  • Deprecate Java-specific types (biginteger, bigdecimal, byte, short, long, double)

    Deprecate Java-specific types (biginteger, bigdecimal, byte, short, long, double)

    Is your feature request related to a problem? Please describe.

    While working on #43 it struck me that all the parameter types that are java-specific (biginteger, bigdecimal, byte, short, long, double) don't need an explicit parameter type:

    An {int} parameter can be transformed to any of the following classes:

    • java.lang.Byte
    • java.lang.Short
    • java.lang.Integer
    • java.lang.Long
    • java.math.BigInteger

    A {float} parameter can be transformed to any of the following classes:

    • java.lang.Float
    • java.lang.Doublet
    • java.math.BigDecimal

    Deciding what class to transform to would first use the class from the corresponding method parameter's Java type. If the Java type isn't available (e.g. for dynamically typed languages), the appropriate type would be chosen based on the string value - we'd try to fit it into the "biggest" type. E.g. "127" becomes java.lang.Byte, "128" becomes java.lang.Short etc.

    A similar algorithm could be used for float.

    The main reason I want to do this is to solve the "different parameter types for different platforms" problem described in #43, but with a cleaner (IMO) solution.

    Another reason I want to do this is to avoid having different parameter types for different platforms, which makes it harder to implement cross-platform tools (such as the Cucumber Language Server).

    Describe the solution you'd like

    The gist of the solution is described above, but I'd also like this to be backwards compatible. Using any of the deprecated types will print a warning, encouraging users to switch to {int} or {float}. Implementation-wise, the deprecated types would just be aliases for the {int} or {float} types.

    Describe alternatives you've considered #43 is an alternative I have considered.

    Additional context Add any other context or screenshots about the feature request here.

    opened by aslakhellesoy 8
  • Extract compiler

    Extract compiler

    🤔 What's changed?

    Compilation of a Cucumber Expression AST to a RegExp is extracted to two separate classes:

    • AbstractCompiler
    • RegExpCompiler

    ⚡️ What's your motivation?

    In order to fix https://github.com/cucumber/language-service/issues/16 we need to be able to generate a Gherkin step text from a Cucumber Expression. For example, we should be able to generate I have 0 cukes from the Cucumber Expression I have {int} cukes.

    This can be done by subclassing AbstractCompiler and generating steps instead of regexps.

    🏷️ What kind of change is this?

    • :bank: Refactoring/debt/DX (improvement to code design, tooling, documentation etc. without changing behaviour)

    ♻️ Anything particular you want feedback on?

    I don't think this is necessary to port to the other languages. Being able to extend the compiler in this way is only needed by the language server.

    opened by aslakhellesoy 6
  • Update dependency eslint-plugin-react to v7.29.0

    Update dependency eslint-plugin-react to v7.29.0

    WhiteSource Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | eslint-plugin-react | 7.28.0 -> 7.29.0 | age | adoption | passing | confidence |


    Release Notes

    yannickcr/eslint-plugin-react

    v7.29.0

    Compare Source

    Added
    Fixed
    Changed

    Configuration

    📅 Schedule: At any time (no schedule defined).

    🚦 Automerge: Disabled due to failing status checks.

    Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, click this checkbox.

    This PR has been generated by WhiteSource Renovate. View repository job log here.

    :robot: dependencies 
    opened by renovate[bot] 6
  • Refactor new tokenizer

    Refactor new tokenizer

    Gets rid of almost all the mutable state by using a Cursor to move along the input string.

    The Cursor#scan method emits a token and returns a new Cursor positioned after the token that was emitted.

    opened by mattwynne 6
  • Move documentation from the docs repo

    Move documentation from the docs repo

    Description

    Document Cucumber Expressions in the same repo where their implementation lives.

    Motivation & context

    Update required of cucumber.io/docs

    Ref: https://github.com/cucumber/docs/pull/667

    Checklist:

    • [ ] My code follows the code style of this project.
    • [x] My change requires a change to the documentation.
    • [ ] I have updated the documentation accordingly.
    • [x] I have read the CONTRIBUTING document.
    • [ ] I have added tests to cover my changes.
    • [ ] All new and existing tests passed.
    opened by aslakhellesoy 6
  • [Java] Improve expression creation performance

    [Java] Improve expression creation performance

    🤔 What's changed?

    Refactored ExpressionFactory to improve expression creation performance by about 50%.

    ⚡️ What's your motivation?

    Fixes #185

    🏷️ What kind of change is this?

    • :bank: Refactoring/debt/DX (improvement to code design, tooling, documentation etc. without changing behaviour)

    ♻️ Anything particular you want feedback on?

    The PR has been asked by mpkorstanje

    📋 Checklist:

    • [x] I agree to respect and uphold the Cucumber Community Code of Conduct
    • [ ] I've changed the behaviour of the code
      • [x] I have added/updated tests to cover my changes.
    • [ ] My change requires a change to the documentation.
      • [ ] I have updated the documentation accordingly.
    • [x] Users should know about my change
      • [x] I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.
    opened by jkronegg 5
  • `CucumberExpression.escapeRegex` performance improvement

    `CucumberExpression.escapeRegex` performance improvement

    🤔 What's changed?

    Improved CucumberExpression.escapeRegex(String) performance as proposed in https://github.com/cucumber/cucumber-expressions/issues/200. Calls to escapeRegex are about 7 times faster and the overall performance improvement on CucumberExpression new instance is about 7%.

    ⚡️ What's your motivation?

    Fixes #200

    🏷️ What kind of change is this?

    • :bank: Refactoring/debt/DX (improvement to code design, tooling, documentation etc. without changing behaviour)

    ♻️ Anything particular you want feedback on?

    Unit tests have been executed on the previous implementation and proposed implementation to prevent regressions.

    📋 Checklist:

    • [x] I agree to respect and uphold the Cucumber Community Code of Conduct
    • [ ] I've changed the behaviour of the code
      • [x] I have added/updated tests to cover my changes.
    • [ ] My change requires a change to the documentation.
      • [ ] I have updated the documentation accordingly.
    • [x] Users should know about my change
      • [x] I have added an entry to the "Unreleased" section of the CHANGELOG, linking to this pull request.
    opened by jkronegg 0
  • Bad CucumberExpression creation performance

    Bad CucumberExpression creation performance

    👓 What did you see?

    On my project with about 150 stepdefs and about 400 test scenarios, the IntelliJ profiler says the CucumberExpression.<init> method takes 25.9% of the total CPU time. This is because the method is called for all step defs and for all test scenarios. I think the performance could be better.

    ✅ What did you expect to see?

    I expect CucumberExpression.<init> to avoid unnecessary processing (contributes to #2035).

    I understand that cucumber-java8 can introduce dynamic behavior which requires parsing the expressions for each test scenario. However, I think we can safely cache everything that is constant and does not depend on cucumber-java8. I identitifed the following performance improvement points in CucumberExpression:

    • TreeRegex creation: in CucumberExpression constructor, this object serves to get some "metadata" about a regular expression itself (i.e. not depending on context). Thus, two identical regular expressions will lead to the same TreeRegp, so the creation is cacheable.

      The original code:

      this.treeRegexp = new TreeRegexp(pattern);
      

      could be replaced by (treeRegexps is a static Map<String, TreeRegexp>):

      this.treeRegexp = treeRegexps.computeIfAbsent(pattern, TreeRegexp::new);
      
    • calls to escapeRegex in the rewriteToRegex method are done on the Node.text() content: two identical Node.text() will lead to the same escaped result, independently of the context. Thus, the result of escapeRegex is cacheable.

      The original code:

      return escapeRegex(node.text());
      

      can be replaced by (escapedTexts is a static Map<String, String>):

      return escapedTexts.computeIfAbsent(node.text(), CucumberExpression::escapeRegex);
      

    These two optimization points lead to four combinations to be benchmarked (original version is createExpression0). The benchmark consists in creating 400 times five different expressions:

    | Benchmark | cached calls to escapeRegex | cached TreeRegex creation | ops/s | |-----------------------------------------------|-----------------------------|---------------------------|-----------------| | CucumberExpressionBenchmark.createExpression0 | no | no | 153,024 ± 13,800 | | CucumberExpressionBenchmark.createExpression1 | yes | no | 181,960 ± 12,133 | | CucumberExpressionBenchmark.createExpression2 | no | yes | 186,236 ± 11,232 | | CucumberExpressionBenchmark.createExpression3 | yes | yes | 219,890 ± 12,365 |

    Caching the TreeRegex creation lead to 22% performance improvement and using both methods lead to 44% performance improvement.

    On a real project with about 150 stepdefs and 400 test scenarios, the IntelliJ Profiler runs is about 7700 ms and says that CucumberExpression.<init> is:

    • 25.9% of the total CPU time with the original version (1994 ms)
    • 15.7% of the total CPU time with both optimizations enabled (1209 ms, i.e. that's a 785 ms improvement on total time, or 10%)

    I suggest to use the variant createExpression3 and I would be happy to propose a PR.

    📦 Which tool/library version are you using?

    Cucumber 7.10.1

    🔬 How could we reproduce it?

    The benchmark with the four variants is in cucumberexpressions.zip

    Steps to reproduce the behavior:

    1. Create a Maven project with the following dependencies:

       <dependency>
           <groupId>io.cucumber</groupId>
           <artifactId>cucumber-java</artifactId>
           <version>${cucumber.version}</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>io.cucumber</groupId>
           <artifactId>cucumber-junit-platform-engine</artifactId>
           <version>${cucumber.version}</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>io.cucumber</groupId>
           <artifactId>cucumber-picocontainer</artifactId>
           <version>${cucumber.version}</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>org.openjdk.jmh</groupId>
           <artifactId>jmh-generator-annprocess</artifactId>
           <version>1.36</version>
           <scope>test</scope>
       </dependency>
      
    2. Run the benchmark

    opened by jkronegg 6
  • Optimize Cucumber expression creation in .Net implementation

    Optimize Cucumber expression creation in .Net implementation

    🤔 What's the problem you're trying to solve?

    With #187 optimizations were submitted to create Cucumber expressions more efficiently when using Java. These changes are not applicable the other implementations as these have regular expression support build into the language itself.

    Except .Net

    ✨ What's your proposed solution?

    Port the changes made in #187 to ExpressionFactory.cs and CucumberExpression.cs.

    :pray: help wanted good first issue 
    opened by mpkorstanje 0
  • Use action-publish-pypi in cucumber-expressions

    Use action-publish-pypi in cucumber-expressions

    See https://github.com/cucumber/cucumber-expressions/blob/main/.github/workflows/release-python.yml and https://github.com/cucumber/action-publish-pypi

    opened by mattwynne 0
  • Expression for an argument list

    Expression for an argument list

    🤔 What's the problem you're trying to solve?

    In some cases it might be helpful to have a way of declaring several instances of one type as an expression, e.g. Given the customer selects product(s) {product}+ which could match something like:

    Given the customer selects product bike Given the customer selects products bike, car Given the customer selects products bike, car, skateboard

    and for a better flow maybe also with a filler:

    Given the customer selects products bike and car Given the customer selects products bike, car or skateboard

    What already works is something like this:

      val separators = arrayOf(",", ";", "and", "or")
    
      @ParameterType("^(?:(?:,|;|and|or)?\s?\w+)+$")
      fun products(product: String): List<Product> {
        return product.split(*separators)
          .map { it.trim() }
          .map { Product(it) }
      }
    
    

    This has the disadvantage, that the regex (if specific things still should be checked) might get complex, since it also has to include all separators and the possibility of them being there or not. Also, the complete string (incl. separators) is highlighted in the feature files. Hence, having that as a feature of cucumber expressions would be nice, since it might make the used regex easier. And might also help with the highlighting in the feature files, since the separators could be displayed in another color.

    ✨ What's your proposed solution?

    I could imagine two different ways. For both ways the definition of the parameter type might be kind of the same like it is now (define how the transformation is done for one single element), but it could define separators:

      @ParameterType(regex = "\\w+", separators=[",", ";", "and", "or"])
      fun product(product: String): List<Product> {
        return Product(it)
      }
    

    Option one: a special notation for marking an expression as "vararg", e.g. {name}+

    If the + is provided, the method signature must contain a collection type:

     @Given("the customer selects product(s) {product}+")
      fun givenCustomerSelectsProduct(product: List<Product>) { \* ... *\ }
    

    Option two: no special expression syntax - instead it depends on the method signature if it is a single value or a collection of values is provided.

    So both would be possible:

     @Given("the customer selects product(s) {product}")
      fun givenCustomerSelectsProduct(product: Product) { \* ... *\ }
    

    and

     @Given("the customer selects product(s) {product}")
      fun givenCustomerSelectsProduct(product: List<Product>) { \* ... *\ }
    
    opened by mmiikkkkaa 4
  • Allow free-form text in optionals

    Allow free-form text in optionals

    🤔 What's the problem you're trying to solve?

    I'd like to have optional free-form text in my steps:

    For instance:

    Then error 123 is reported (because reasons)
    

    The "because reasons" string isn't fixed, the content of the parenthesis varies depending on the scenario.

    ✨ What's your proposed solution?

    It would be nice to either:

    • have a way to use some kind of "catch-all" structure (here .*) in optionals: error {int} is reported( \\(.*)
    • or allow parameters in optionals error {int} is reported( \\({})

    ⛏ Have you considered any alternatives or workarounds?

    I tried using an anonymous parameter:

    error {int} is reported( \\(){}

    and ignore the related parameter in the step definition.

    but this is not possible in my case, since I also have a step for:

    error {int} is reported {int} times( \\(){}

    which causes an ambiguous step definition.

    This is why I'd need to put the anonymous part within the optional:

    error {int} is reported( \\({})

    But then it is an illegal expression (parameters are not allowed in optionals).

    I also tried using a comment at the end of the expression:

    Then error 123 is reported #(because reasons)

    but comments are only allowed as a start of a new line.

    The only resort is to use a regex. But the expressions then get quite ugly and unreadable (the examples above are simplified, my real expressions are more complex). Or move the free-form text to its own line, but it is definitely less concise and sort of breaks the scenario flow.

    These two workarounds work, but are suboptimal as they unfortunately make for less readable code.

    📚 Any additional context?

    I recently used cucumber v4.5.4 (cucumber-java), and the following expressions just worked for my use case:

    error {int} is reported( \\(.*)`
    
    error {int} is reported {int} time(s)( \\(.*)
    

    This stopped working when migrating to cucumber v7.8.0!

    opened by rdeltour 1
Releases(v16.1.1)
Owner
Cucumber
Cucumber Open
Cucumber
Java regular expressions made easy.

JavaVerbalExpressions VerbalExpressions is a Java library that helps to construct difficult regular expressions. Getting Started Maven Dependency: <de

null 2.6k Dec 30, 2022
A complete and performing library to highlight text snippets (EditText, SpannableString and TextView) using Spannable with Regular Expressions (Regex) for Android.

Highlight A complete and performing library to highlight text snippets (EditText/Editable and TextView) using Spannable with Regular Expressions (Rege

Irineu A. Silva 16 Dec 22, 2022
Easy-to-use placeholder library to focus on replacement of regular expressions inside a text.

WPlaceholder Flexible library to replace placeholders inside messages/texts with Regex expressions. For what it's good for Placeholder replacement is

Luiz Otávio 7 Oct 11, 2022
Annotation processor to create immutable objects and builders. Feels like Guava's immutable collections but for regular value objects. JSON, Jackson, Gson, JAX-RS integrations included

Read full documentation at http://immutables.org // Define abstract value type using interface, abstract class or annotation @Value.Immutable public i

Immutables 3.2k Dec 31, 2022
Backport of Java 8's lambda expressions to Java 7, 6 and 5

Retrolambda: Use Lambdas on Java 7 Just as there was Retroweaver et al. for running Java 5 code with generics on Java 1.4, Retrolambda lets you run Ja

Esko Luontola 3.5k Dec 30, 2022
An efficient and flexible token-based regular expression language and engine.

OpenRegex OpenRegex is written by Michael Schmitz at the Turing Center http://turing.cs.washington.edu/. It is licensed under the lesser GPL. Please s

KnowItAll 74 Jul 12, 2022
ReDoSHunter: A Combined Static and Dynamic Approach for Regular Expression DoS Detection

ReDoSHunter ReDoSHunter is a combined static and dynamic approach for regular expression DoS detection. LATEST NOTE (updated at 2021.09.13): ReDoSHunt

Yeting Li 43 Dec 23, 2022
MathParser - a simple but powerful open-source math tool that parses and evaluates algebraic expressions written in pure java

MathParser is a simple but powerful open-source math tool that parses and evaluates algebraic expressions written in pure java. This projec

AmirHosseinAghajari 40 Dec 24, 2022
A plugin of Grasscutter for send regular notice.

MeaNotice - Grasscutter Regular Notice Plugin MeaNotice is a plugin of Grasscutter, you can use this plugin to publish notifications in-game regularly

ButterCookies 39 Oct 17, 2022
EvalEx is a handy expression evaluator for Java, that allows to evaluate expressions.

EvalEx - Java Expression Evaluator EvalEx is a handy expression evaluator for Java, that allows to parse and evaluate expression strings. Key Features

null 18 Sep 18, 2022
Support alternative markup for Apache Maven POM files

Overview Polyglot for Maven is a set of extensions for Maven 3.3.1+ that allows the POM model to be written in dialects other than XML. Several of the

null 828 Dec 17, 2022
Fast and Easy mapping from database and csv to POJO. A java micro ORM, lightweight alternative to iBatis and Hibernate. Fast Csv Parser and Csv Mapper

Simple Flat Mapper Release Notes Getting Started Docs Building it The build is using Maven. git clone https://github.com/arnaudroger/SimpleFlatMapper.

Arnaud Roger 418 Dec 17, 2022
Object-Oriented Java primitives, as an alternative to Google Guava and Apache Commons

Project architect: @victornoel ATTENTION: We're still in a very early alpha version, the API may and will change frequently. Please, use it at your ow

Yegor Bugayenko 691 Dec 27, 2022
A lightweight and performant Java ORM alternative.

LightORM A lightweight and performant Java ORM alternative. LightORM has annotation processors so that all the integration code with the database is g

Jailson Pereira 14 Nov 22, 2022
An open source, modular alternative of sketchware. Create your own app in android using block programming like scratch!

OpenBlocks An open source, modular alternative of sketchware. Create your own app in android using block programming like scratch! What is OpenBlocks?

OpenBlocks 30 Dec 16, 2022
Highly experimental and unstable alternative world format for Minecraft

Radon for Fabric An alternative world storage format that tries to be more performant and durable than vanilla's own. This is hardly more than a day's

JellySquid 48 Dec 9, 2022
ActiveJ is an alternative Java platform built from the ground up. ActiveJ redefines web, high load, and cloud programming in Java, featuring ultimate performance and scalability!

Introduction ActiveJ is a full-featured modern Java platform, created from the ground up as an alternative to Spring/Micronauts/Netty/Jetty. It is des

ActiveJ LLC 579 Jan 7, 2023
Your new way of getting player input. An alternative to the Conversation API

Dialogue Dialogue is a Spigot API that completely revamps the Conversation API. This is not a plugin you put on your server. Want to know what's curre

nthByte 16 Aug 26, 2022