Skip to content

Add name capture group support for regex triggers#4731

Merged
Delwing merged 4 commits intoMudlet:developmentfrom
Delwing:name-capture-groups
Feb 7, 2021
Merged

Add name capture group support for regex triggers#4731
Delwing merged 4 commits intoMudlet:developmentfrom
Delwing:name-capture-groups

Conversation

@Delwing
Copy link
Copy Markdown
Contributor

@Delwing Delwing commented Feb 1, 2021

Brief overview of PR changes/additions

It populates matches with named capture groups:
https://www.regular-expressions.info/named.html

Some skeletal retrieval was there, but never went any further.

I've tested that on regexp trigger and tempRegexTrigger - I guess only those 2 need support for that.
Multimatches also are made to work.

Please take a special look at the retrieval code TTrigger.ccp:352

Motivation for adding to Mudlet

Multiple triggers matching similar thing can be hell if searched needle is swapping place.
Named groups are very convinent.

Other info (issues closed, discussion etc)

Quick test regexp

if demoRegex then
  killTrigger(demoRegex)
end
demoRegex = tempRegexTrigger("^My name is (?<name>\\w+)\\.$", function() display(matches) cecho("\n<red>".. matches.name) end)
feedTriggers("\nMy name is Dargoth.\n")
echo("\n")

@Delwing Delwing requested a review from a team as a code owner February 1, 2021 22:02
@Delwing Delwing requested review from a team February 1, 2021 22:02
@add-deployment-links
Copy link
Copy Markdown

add-deployment-links bot commented Feb 1, 2021

Hey there! Thanks for helping Mudlet improve. 🌟

Test versions

You can directly test the changes here:

No need to install anything - just unzip and run.
Let us know if it works well, and if it doesn't, please give details.

Copy link
Copy Markdown
Member

@SlySven SlySven left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of this - not sure I can get my head around it at the moment though...

😵

matchStatePair.second->conditionMatched();
matchStatePair.second->multiCaptureList.push_back(captureList);
matchStatePair.second->multiCapturePosList.push_back(posList);
if (nameMatches != nullptr) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The != nullptr is unneeded...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will remove it and test 👍🏻

Copy link
Copy Markdown
Member

@vadi2 vadi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well 👍

image


tabptr = name_table;
for (i = 0; i < namecount; i++) {
int n = (tabptr[0] << 8) | tabptr[1];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment for this construction?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... I can reference snippet that I've used in comment + my (hopefully) correct understanding of that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would work

@@ -13653,10 +13653,11 @@ std::pair<bool, QString> TLuaInterpreter::discordApiEnabled(lua_State* L, bool w
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for people to be able to check in their scripts if the player is running a Mudlet that supports this - add namedmatches = true to mudlet.supports, similar to how coroutines are there already.

See also https://wiki.mudlet.org/w/Manual:Advanced_Lua#Coroutines

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea!

src/TTrigger.cpp Outdated
Comment on lines +466 to +467
NameGroupMatches* ng = &nameGroups;
updateMultistates(regexNumber, captureList, posList, ng);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would work just as well:

Suggested change
NameGroupMatches* ng = &nameGroups;
updateMultistates(regexNumber, captureList, posList, ng);
updateMultistates(regexNumber, captureList, posList, &nameGroups);

#define REGEX_PROMPT 7
#define MAX_CAPTURE_GROUPS 33

using NameGroupMatches = QVector<QPair<QString, QString>>;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤯 This is a new concept for me - anyone else not get it? https://stackoverflow.com/q/20790932/4805858 might help.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to have this generics more comprehensible.

src/TTrigger.cpp Outdated
tabptr = name_table;
for (i = 0; i < namecount; i++) {
int n = (tabptr[0] << 8) | tabptr[1];
auto name = QString::asprintf("%*s", name_entry_size - 3, tabptr + 2).trimmed();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qt documentation says:

Warning: We do not recommend using QString::asprintf() in new Qt code. Instead, consider using QTextStream or arg(), both of which support Unicode strings seamlessly and are type-safe. Here's an example that uses QTextStream:

QString result;
QTextStream(&result) << "pi = " << 3.14;
// result == "pi = 3.14"
For translations, especially if the strings contains more than one escape sequence, you should consider using the arg() function instead. This allows the order of the replacements to be controlled by the translator.

This function was introduced in Qt 5.5.

See also arg().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! I've read it, and was pretty aware of that. arg() was not alternative in this case, not accepting range I guess... My understanding of this part is a bit limited.
It is based on:
https://github.com/vmg/pcre/blob/master/pcredemo.c

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I've found solution not to use asprintf

@SlySven
Copy link
Copy Markdown
Member

SlySven commented Feb 4, 2021

👍 You know named capture groups is a great way to simplify multiple trigger items with different numbers of arguments and them not being in the same position in different ones...! Something that really should be mentioned in the release announcement.


tabptr = name_table;
for (i = 0; i < namecount; i++) {
int n = (tabptr[0] << 8) | tabptr[1];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would work

@Delwing
Copy link
Copy Markdown
Contributor Author

Delwing commented Feb 4, 2021

That was my main motivation - same handler function, different argument order :) Had just use case like that, so started digging :)

@vadi2
Copy link
Copy Markdown
Member

vadi2 commented Feb 4, 2021

Include that in the docs for sure as a practical example!

@Delwing
Copy link
Copy Markdown
Contributor Author

Delwing commented Feb 4, 2021

Yep! Will do.

@Delwing Delwing changed the title add name capture group support Add name capture group support for regex triggers Feb 4, 2021
@Delwing Delwing merged commit 27d4785 into Mudlet:development Feb 7, 2021
Chris7 pushed a commit to Chris7/Mudlet that referenced this pull request Jan 2, 2022
Co-authored-by: Piotr Wilczynski <piotr.wilczynski@bisnode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants