![](/img/trans.png)
[英]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.