[英]How can I get the next string, in alphabetical DESCENDING order, in Python?
[英]How can I use Regex to find a string of characters in alphabetical order using Python?
所以我遇到了一个挑战 - 在字符串中找到最长的字母字符字符串。 例如,“abcghiijkyxz”应该导致“ghiijk”(是的,i 加倍了)。
我一直在用循环来解决这个问题——迭代整个字符串,然后对每个字符,使用lower和ord开始第二个循环。 无需帮助编写该循环。
但是,有人建议我使用 Regex 来处理这类事情。 我的正则表达式很弱(我知道如何获取静态集,我的前瞻知识扩展到知道它们存在)。 我将如何编写一个正则表达式来展望未来,并按字母顺序检查未来的字符? 还是建议使用 Regex 对此类事情不切实际?
编辑:普遍的共识似乎是正则表达式对于这类事情确实很糟糕。
只是为了说明为什么正则表达式是不是这样的事情实用,这里是一个正则表达式,将匹配ghiijk
在你给出的例子abcghiijkyxz
。 请注意,它还会匹配abc
、 y
、 x
、 z
因为从技术上讲,它们应该被视为按顺序排列的最长字母字符串。 不幸的是,您无法单独使用正则表达式确定哪个最长,但这确实为您提供了所有可能性。 请注意,此正则表达式适用于 PCRE,不适用于 python 的re
模块! 另请注意, python 的regex
库当前不支持(*ACCEPT)
。 虽然我还没有测试过, pyre2 包(使用 Cython 的谷歌 re2 pyre2 的 python 包装器)声称它支持(*ACCEPT)
控制动词,所以目前使用 python可能是可能的。
((?:a+(?(?!b)(*ACCEPT))|b+(?(?!c)(*ACCEPT))|c+(?(?!d)(*ACCEPT))|d+(?(?!e)(*ACCEPT))|e+(?(?!f)(*ACCEPT))|f+(?(?!g)(*ACCEPT))|g+(?(?!h)(*ACCEPT))|h+(?(?!i)(*ACCEPT))|i+(?(?!j)(*ACCEPT))|j+(?(?!k)(*ACCEPT))|k+(?(?!l)(*ACCEPT))|l+(?(?!m)(*ACCEPT))|m+(?(?!n)(*ACCEPT))|n+(?(?!o)(*ACCEPT))|o+(?(?!p)(*ACCEPT))|p+(?(?!q)(*ACCEPT))|q+(?(?!r)(*ACCEPT))|r+(?(?!s)(*ACCEPT))|s+(?(?!t)(*ACCEPT))|t+(?(?!u)(*ACCEPT))|u+(?(?!v)(*ACCEPT))|v+(?(?!w)(*ACCEPT))|w+(?(?!x)(*ACCEPT))|x+(?(?!y)(*ACCEPT))|y+(?(?!z)(*ACCEPT))|z+(?(?!$)(*ACCEPT)))+)
结果是:
abc
ghiijk
y
x
z
单个选项的解释,即a+(?(?!b)(*ACCEPT))
:
a+
匹配a
(字面意思)一次或多次。 这会捕获几个相同字符按顺序排列的实例,例如aa
。(?(?!b)(*ACCEPT))
If 子句评估条件。
(?!b)
if 子句的条件。 负前瞻确保接下来的不是b
。 这是因为如果不是b
,我们希望下面的控制动词生效。(*ACCEPT)
如果满足条件(以上),我们接受当前的解决方案。 此控制动词使正则表达式成功结束,跳过模式的其余部分。 由于此标记位于捕获组内,因此只有该捕获组在该特定位置成功结束,而父模式继续执行。 那么如果条件不满足会发生什么? 嗯,这意味着(?!b)
评估为假。 这意味着后面的字符实际上是b
,因此我们允许匹配(在这种情况下是捕获)继续。 请注意,整个模式都包含在(?:)+
,这允许我们匹配连续的选项,直到遇到(*ACCEPT)
控制动词或行尾。
整个正则表达式的唯一例外是z
。 由于它是英文字母表中的最后一个字符(我认为这是这个问题的目标),我们不关心后面是什么,所以我们可以简单地输入z+(?(?!$)(*ACCEPT))
,这将确保在z
之后没有任何匹配。 相反,如果您想要匹配za
(圆形字母顺序匹配 - idk,如果这是正确的术语,但对我来说听起来很正确),您可以使用z+(?(?!a)(*ACCEPT)))+
如所见在这里。
如前所述,正则表达式不是最好的工具。 由于您对连续序列感兴趣,您可以使用单个 for 循环来执行此操作:
def LNDS(s):
start = 0
cur_len = 1
max_len = 1
for i in range(1,len(s)):
if ord(s[i]) in (ord(s[i-1]), ord(s[i-1])+1):
cur_len += 1
else:
if cur_len > max_len:
max_len = cur_len
start = i - cur_len
cur_len = 1
if cur_len > max_len:
max_len = cur_len
start = len(s) - cur_len
return s[start:start+max_len]
>>> LNDS('abcghiijkyxz')
'ghiijk'
我们保持了我们看到的非递减字符的总数,当非递减序列结束时,我们将它与我们之前看到的最长非递减序列进行比较,如果它更长,则更新我们的“迄今为止最好看的” .
生成所有正则表达式子串,如 ^a+b+c+$(最长到最短)。 然后将每个正则表达式与“abcghiijkyxz”的所有子字符串(最长到最短)进行匹配,并在第一个匹配处停止。
def all_substrings(s):
n = len(s)
for i in xrange(n, 0, -1):
for j in xrange(n - i + 1):
yield s[j:j + i]
def longest_alphabetical_substring(s):
for t in all_substrings("abcdefghijklmnopqrstuvwxyz"):
r = re.compile("^" + "".join(map(lambda x: x + "+", t)) + "$")
for u in all_substrings(s):
if r.match(u):
return u
print longest_alphabetical_substring("abcghiijkyxz")
打印“ghiijk”。
正则表达式: char+
表示a+b+c+...
细节:
+
匹配一次和无限次蟒蛇代码:
import re
def LNDS(text):
array = []
for y in range(97, 122): # a - z
st = r"%s+" % chr(y)
for x in range(y+1, 123): # b - z
st += r"%s+" % chr(x)
match = re.findall(st, text)
if match:
array.append(max(match, key=len))
else:
break
if array:
array = [max(array, key=len)]
return array
输出:
print(LNDS('abababababab abc')) >>> ['abc']
print(LNDS('abcghiijkyxz')) >>> ['ghiijk']
对于字符串abcghiijkyxz
正则表达式模式:
a+b+ i+j+k+l+
a+b+c+ j+k+
a+b+c+d+ j+k+l+
b+c+ k+l+
b+c+d+ l+m+
c+d+ m+n+
d+e+ n+o+
e+f+ o+p+
f+g+ p+q+
g+h+ q+r+
g+h+i+ r+s+
g+h+i+j+ s+t+
g+h+i+j+k+ t+u+
g+h+i+j+k+l+ u+v+
h+i+ v+w+
h+i+j+ w+x+
h+i+j+k+ x+y+
h+i+j+k+l+ y+z+
i+j+
i+j+k+
要真正“解决”问题,您可以使用
string = 'abcxyzghiijkl'
def sort_longest(string):
stack = []; result = [];
for idx, char in enumerate(string):
c = ord(char)
if idx == 0:
# initialize our stack
stack.append((char, c))
elif idx == len(string) - 1:
result.append(stack)
elif c == stack[-1][1] or c == stack[-1][1] + 1:
# compare it to the item before (a tuple)
stack.append((char, c))
else:
# append the stack to the overall result
# and reinitialize the stack
result.append(stack)
stack = []
stack.append((char, c))
return ["".join(item[0]
for item in sublst)
for sublst in sorted(result, key=len, reverse=True)]
print(sort_longest(string))
哪个产量
['ghiijk', 'abc', 'xyz']
在这个例子中。
ord()
由您的要求填充的stack
变量。
使用正则表达式真的很容易!
(在此处使用尾随上下文)
rexp=re.compile(
"".join(['(?:(?=.' + chr(ord(x)+1) + ')'+ x +')?'
for x in "abcdefghijklmnopqrstuvwxyz"])
+'[a-z]')
a = 'bcabhhjabjjbckjkjabckkjdefghiklmn90'
re.findall(rexp, a)
#Answer: ['bc', 'ab', 'h', 'h', 'j', 'ab', 'j', 'j', 'bc', 'k', 'jk', 'j', 'abc', 'k', 'k', 'j', 'defghi', 'klmn']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.