increased utility of string matching using '~'

This commit is contained in:
gnembon committed 2020-09-26 12:28:46 -03:00
1 parent 677ff2da90
commit c4c268b079
4 files changed
+39 -4

No files matched your search

+13 -1
View File
@@ -383,7 +383,12 @@ TODO: add more information about l-value behaviour.
### `Matching Operator ~` ### `Matching Operator ~`
This operator should be understood as 'matches', 'contains', 'is_in', or 'find me some stuff about something else. This operator should be understood as 'matches', 'contains', 'is_in', or 'find me some stuff about something else.
For strings it matches the right operand as a regular expression to the left, returning the first match. For strings it matches the right operand as a regular expression to the left, returning:
- `null` if there is no match
- matched phrase if no grouping is applied
- matched element if one group is applied
- list of matches if more than one grouping is applied
This can be used to extract information from unparsed nbt's in a more convoluted way (use `get(...)` for This can be used to extract information from unparsed nbt's in a more convoluted way (use `get(...)` for
more appropriate way of doing it). For lists it checks if an element is in the list, and returns the more appropriate way of doing it). For lists it checks if an element is in the list, and returns the
index of that element, or `null` if no such element was found, especially that the use of `first(...)` index of that element, or `null` if no such element was found, especially that the use of `first(...)`
@@ -397,7 +402,14 @@ any extra arguments.
<pre> <pre>
l(1,2,3) ~ 2 => 1 l(1,2,3) ~ 2 => 1
l(1,2,3) ~ 4 => null l(1,2,3) ~ 4 => null
'foobar' ~ 'baz' => null
'foobar' ~ '.b' => 'ob' 'foobar' ~ '.b' => 'ob'
'foobar' ~ '(.)b' => 'o'
'foobar' ~ '((.)b)' => ['ob', 'o']
'foobar' ~ '((.)(b))' => ['ob', 'o', 'b']
'foobar' ~ '(?:(.)(?:b))' => 'o'
player('*') ~ 'gnembon' // null unless player gnembon is logged in (better to use player('gnembon') instead player('*') ~ 'gnembon' // null unless player gnembon is logged in (better to use player('gnembon') instead
p ~ 'sneaking' // if p is an entity returns whether p is sneaking p ~ 'sneaking' // if p is an entity returns whether p is sneaking
</pre> </pre>
+13 -1
View File
@@ -59,7 +59,12 @@ TODO: add more information about l-value behaviour.
### `Matching Operator ~` ### `Matching Operator ~`
This operator should be understood as 'matches', 'contains', 'is_in', or 'find me some stuff about something else. This operator should be understood as 'matches', 'contains', 'is_in', or 'find me some stuff about something else.
For strings it matches the right operand as a regular expression to the left, returning the first match. For strings it matches the right operand as a regular expression to the left, returning:
- `null` if there is no match
- matched phrase if no grouping is applied
- matched element if one group is applied
- list of matches if more than one grouping is applied
This can be used to extract information from unparsed nbt's in a more convoluted way (use `get(...)` for This can be used to extract information from unparsed nbt's in a more convoluted way (use `get(...)` for
more appropriate way of doing it). For lists it checks if an element is in the list, and returns the more appropriate way of doing it). For lists it checks if an element is in the list, and returns the
index of that element, or `null` if no such element was found, especially that the use of `first(...)` index of that element, or `null` if no such element was found, especially that the use of `first(...)`
@@ -73,7 +78,14 @@ any extra arguments.
<pre> <pre>
l(1,2,3) ~ 2 => 1 l(1,2,3) ~ 2 => 1
l(1,2,3) ~ 4 => null l(1,2,3) ~ 4 => null
'foobar' ~ 'baz' => null
'foobar' ~ '.b' => 'ob' 'foobar' ~ '.b' => 'ob'
'foobar' ~ '(.)b' => 'o'
'foobar' ~ '((.)b)' => ['ob', 'o']
'foobar' ~ '((.)(b))' => ['ob', 'o', 'b']
'foobar' ~ '(?:(.)(?:b))' => 'o'
player('*') ~ 'gnembon' // null unless player gnembon is logged in (better to use player('gnembon') instead player('*') ~ 'gnembon' // null unless player gnembon is logged in (better to use player('gnembon') instead
p ~ 'sneaking' // if p is an entity returns whether p is sneaking p ~ 'sneaking' // if p is an entity returns whether p is sneaking
</pre> </pre>
@@ -29,7 +29,7 @@ public abstract class PlayerInventory_scarpetEventMixin
Item item = stack.getItem(); Item item = stack.getItem();
int count = stack.getCount(); int count = stack.getCount();
boolean res = playerInventory.insertStack(-1, stack); boolean res = playerInventory.insertStack(-1, stack);
if (res) if (count != stack.getCount()) // res returns false for larger item adding to a almost full ineventory
{ {
ItemStack diffStack = new ItemStack(item, count - stack.getCount()); ItemStack diffStack = new ItemStack(item, count - stack.getCount());
diffStack.setTag(stack.getTag()); diffStack.setTag(stack.getTag());
+12 -1
View File
@@ -5,6 +5,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -145,7 +147,16 @@ public abstract class Value implements Comparable<Value>, Cloneable
{ {
final Pattern p = Pattern.compile(value1.getString()); final Pattern p = Pattern.compile(value1.getString());
final Matcher m = p.matcher(this.getString()); final Matcher m = p.matcher(this.getString());
return m.find()?new StringValue(m.group()):Value.NULL; if (!m.find()) return Value.NULL;
int gc = m.groupCount();
if (gc == 0) return new StringValue(m.group());
if (gc == 1) return new StringValue(m.group(1));
List<Value> groups = new ArrayList<>(gc);
for (int i = 1; i <= gc; i++)
{
groups.add(new StringValue(m.group(i)));
}
return ListValue.wrap(groups);
} }
public int length() public int length()
{ {