📄 re.java
字号:
case 1:
return start1;
case 2:
return start2;
default:
if (startn == null)
{
allocParens();
}
return startn[which];
}
}
return -1;
}
/**
* Returns the end index of a given paren level.
* @param which Nesting level of subexpression
* @return String index
*/
public final int getParenEnd(int which)
{
if (which < parenCount)
{
switch (which)
{
case 0:
return end0;
case 1:
return end1;
case 2:
return end2;
default:
if (endn == null)
{
allocParens();
}
return endn[which];
}
}
return -1;
}
/**
* Returns the length of a given paren level.
* @param which Nesting level of subexpression
* @return Number of characters in the parenthesized subexpression
*/
public final int getParenLength(int which)
{
if (which < parenCount)
{
return getParenEnd(which) - getParenStart(which);
}
return -1;
}
/**
* Sets the start of a paren level
* @param which Which paren level
* @param i Index in input array
*/
protected final void setParenStart(int which, int i)
{
if (which < parenCount)
{
switch (which)
{
case 0:
start0 = i;
break;
case 1:
start1 = i;
break;
case 2:
start2 = i;
break;
default:
if (startn == null)
{
allocParens();
}
startn[which] = i;
break;
}
}
}
/**
* Sets the end of a paren level
* @param which Which paren level
* @param i Index in input array
*/
protected final void setParenEnd(int which, int i)
{
if (which < parenCount)
{
switch (which)
{
case 0:
end0 = i;
break;
case 1:
end1 = i;
break;
case 2:
end2 = i;
break;
default:
if (endn == null)
{
allocParens();
}
endn[which] = i;
break;
}
}
}
/**
* Throws an Error representing an internal error condition probably resulting
* from a bug in the regular expression compiler (or possibly data corruption).
* In practice, this should be very rare.
* @param s Error description
*/
protected void internalError(String s) throws Error
{
throw new Error("RE internal error: " + s);
}
/**
* Performs lazy allocation of subexpression arrays
*/
private final void allocParens()
{
// Allocate arrays for subexpressions
startn = new int[maxParen];
endn = new int[maxParen];
// Set sub-expression pointers to invalid values
for (int i = 0; i < maxParen; i++)
{
startn[i] = -1;
endn[i] = -1;
}
}
/**
* Try to match a string against a subset of nodes in the program
* @param firstNode Node to start at in program
* @param lastNode Last valid node (used for matching a subexpression without
* matching the rest of the program as well).
* @param idxStart Starting position in character array
* @return Final input array index if match succeeded. -1 if not.
*/
protected int matchNodes(int firstNode, int lastNode, int idxStart)
{
// Our current place in the string
int idx = idxStart;
// Loop while node is valid
int next, opcode, opdata;
int idxNew;
char[] instruction = program.instruction;
for (int node = firstNode; node < lastNode; )
{
opcode = instruction[node + offsetOpcode];
next = node + (short)instruction[node + offsetNext];
opdata = instruction[node + offsetOpdata];
switch (opcode)
{
case OP_RELUCTANTMAYBE:
{
int once = 0;
do
{
// Try to match the rest without using the reluctant subexpr
if ((idxNew = matchNodes(next, maxNode, idx)) != -1)
{
return idxNew;
}
}
while ((once++ == 0) && (idx = matchNodes(node + nodeSize, next, idx)) != -1);
return -1;
}
case OP_RELUCTANTPLUS:
while ((idx = matchNodes(node + nodeSize, next, idx)) != -1)
{
// Try to match the rest without using the reluctant subexpr
if ((idxNew = matchNodes(next, maxNode, idx)) != -1)
{
return idxNew;
}
}
return -1;
case OP_RELUCTANTSTAR:
do
{
// Try to match the rest without using the reluctant subexpr
if ((idxNew = matchNodes(next, maxNode, idx)) != -1)
{
return idxNew;
}
}
while ((idx = matchNodes(node + nodeSize, next, idx)) != -1);
return -1;
case OP_OPEN:
// Match subexpression
if ((program.flags & REProgram.OPT_HASBACKREFS) != 0)
{
startBackref[opdata] = idx;
}
if ((idxNew = matchNodes(next, maxNode, idx)) != -1)
{
// Increase valid paren count
if ((opdata + 1) > parenCount)
{
parenCount = opdata + 1;
}
// Don't set paren if already set later on
if (getParenStart(opdata) == -1)
{
setParenStart(opdata, idx);
}
}
return idxNew;
case OP_CLOSE:
// Done matching subexpression
if ((program.flags & REProgram.OPT_HASBACKREFS) != 0)
{
endBackref[opdata] = idx;
}
if ((idxNew = matchNodes(next, maxNode, idx)) != -1)
{
// Increase valid paren count
if ((opdata + 1) > parenCount)
{
parenCount = opdata + 1;
}
// Don't set paren if already set later on
if (getParenEnd(opdata) == -1)
{
setParenEnd(opdata, idx);
}
}
return idxNew;
case OP_BACKREF:
{
// Get the start and end of the backref
int s = startBackref[opdata];
int e = endBackref[opdata];
// We don't know the backref yet
if (s == -1 || e == -1)
{
return -1;
}
// The backref is empty size
if (s == e)
{
break;
}
// Get the length of the backref
int l = e - s;
// If there's not enough input left, give up.
if (search.isEnd(idx + l - 1))
{
return -1;
}
// Case fold the backref?
if ((matchFlags & MATCH_CASEINDEPENDENT) != 0)
{
// Compare backref to input, case-folding as we go
for (int i = 0; i < l; i++)
{
if (Character.toLowerCase(search.charAt(idx++)) != Character.toLowerCase(search.charAt(s + i)))
{
return -1;
}
}
}
else
{
// Compare backref to input
for (int i = 0; i < l; i++)
{
if (search.charAt(idx++) != search.charAt(s + i))
{
return -1;
}
}
}
}
break;
case OP_BOL:
// Fail if we're not at the start of the string
if (idx != 0)
{
// If we're multiline matching, we could still be at the start of a line
if ((matchFlags & MATCH_MULTILINE) == MATCH_MULTILINE)
{
// If not at start of line, give up
if (idx <= 0 || !isNewline(idx - 1)) {
return -1;
} else {
break;
}
}
return -1;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -