Problem/Motivation

Seeing the discussion in #294218: Turn hook names in theme() and module_invoke() into links, I think we could do with some guidelines for the formatting of long regular expressions. Can they be split up in multiple lines for legibility, just like we do with big arrays? And how exactly?

Benefits

If we adopted this change, the Drupal Project would benefit by ...

Three supporters required

  1. https://www.drupal.org/u/{userid} (yyyy-mm-dd they added support)
  2. https://www.drupal.org/u/{userid} (yyyy-mm-dd they added support)
  3. https://www.drupal.org/u/{userid} (yyyy-mm-dd they added support)

Proposed changes

Provide all proposed changes to the Drupal Coding standards. Give a link to each section that will be changed, and show the current text and proposed text as in the following layout:

1. {link to the documentation heading that is to change}

Current text

Add current text in blockquotes

Proposed text

Add proposed text in blockquotes

2. Repeat the above for each page or sub-page that needs to be changed.

Remaining tasks

  1. Create this issue in the Coding Standards queue, using the defined template
  2. Add supporters
  3. Create a Change Record
  4. Review by the Coding Standards Committee
  5. Coding Standards Committee takes action as required
  6. Discussed by the Core Committer Committee, if it impacts Drupal Core
  7. Final review by Coding Standards Committee
  8. Documentation updates
    1. Edit all pages
    2. Publish change record
    3. Remove 'Needs documentation edits' tag
  9. If applicable, create follow-up issues for PHPCS rules/sniffs changes

For a full explanation of these steps see the Coding Standards project page

Comments

joachim’s picture

I think an awful lot depends on the text that's being matched in the regex -- whether HTML or PHP or something else.

As far as regex syntax goes, personally I like:

- putting the regex outer characters on lines alone, so they're apart from the rest of the thing
- splitting up brackets onto multiple lines, whether they're capturing, noncapturing, or assertions, with the alternation character on its own line (otherwise it feels quite noisy, like it's participating in the thing being matched, and keeping regex syntax apart from actual content is a key goal IMO)
- chunks of actual content alone on lines where feasible

$regex = '[
  foo
  (?=
    bar
    |
    biz
  )
  kha+n # though putting whitespace inside this feels weird
]';
jhodgdon’s picture

We don't put operators on their own lines when splitting up if() or large arithmetic statements. We don't put commas on their own lines when splitting up arrays. So to me, having a line with just one operator or paren on it:

|
(?=
)

is weird, wastes a lot of space, takes a longer time to scan, etc. than a somewhat more compact format.

Also, see http://drupal.org/coding-standards#linelength also for our general guidelines on splitting up lines. Maybe the guideline here should be similar to what's suggested for if() statement conditions -- assign sub-expressions to variables with intuitive names and concatenate them together? That would probably be more readable, use less space than the proposal above, and be self-documenting and more in line with our other coding standards. Something like this maybe:

$match_this = '|...|';
$match_that = '|...|';
$match = "($match_this|$match_that)";
joachim’s picture

I think the pipes in regexes are quite different from commas; they detract significantly from the content if on the same line.

> assign sub-expressions to variables with intuitive names and concatenate them together

Could be a useful tactic. But on the other hand, it can make it harder to see how the regex is working. The example you posted is already broken, for instance ;)

The thing to bear in mind is that regexes are complex beasts and they are pretty much a separate programming language.

jhodgdon’s picture

It was not meant to be a valid example, just an idea. :)

joachim’s picture

Here's more on what I mean by the content of the regex affecting what sort of layout makes sense. In module builder I need to capture portions of the function docblock, the declaration, and the function body. I've laid it out so it more or less matches how the docblock and function are laid out in PHP:

  // The pattern for extracting function data: capture first line of doc,
  // function declaration, and hook name.
  $pattern = '[
           / \* \* \n     # start phpdoc
          \  \* \  ( .* ) \n  # first line of phpdoc: capture the text
      (?: \  \* .* \n )*  # lines of phpdoc
          \  \* /  \n     # end phpdoc
         ( function \ ( hook_\w* ) .* ) \  { # function declaration: capture both entire declaration and name
     ( (?: .* \n )*? )    # function body
         ^ }
  ]mx';  
jhodgdon’s picture

Project: Drupal core » Drupal Technical Working Group
Version: 8.0.x-dev »
Component: other » Documentation
Issue summary: View changes

Coding standards changes are now part of the TWG

tizzo’s picture

Project: Drupal Technical Working Group » Coding Standards
quietone’s picture

Issue summary: View changes

This was discussed at #3456119: Coding Standards Meeting Tuesday 2024-06-18 2100 UTC. We are considering adding something for this but have not settled on any details or where this information would go. So far adding something like, "All regexes with more than one group must have a comment' has been suggested. But that does cover how to make a long regex multi-line. Perhaps just adding an example it the best option here.

I have added the new issue summary template.

quietone’s picture

Component: Documentation » Coding Standards