簡體   English   中英

是否可以編寫Perl / Java / etc正則表達式來匹配十進制(非)素數?

[英]Can a Perl/Java/etc regular expression be written to match decimal (non-)prime numbers?

相關問題/材料:

眾所周知,由各種編程語言支持的“正則表達式”生成在形式意義上非常規的語言,並且如上述材料所示,能夠識別至少一些上下文敏感語言。

語言L = {x | x是基數10中的素數。}是一種上下文敏感語言,因為素數可以通過線性有界自動機來測試(但它不是通過泵浦引理參數的無上下文語言)。

那么,是否可以編寫一個Perl或Java正則表達式,它恰好接受基數為10的所有素數? 如果感覺更容易,可以隨意替換≥2的任何其他基礎或精確識別所有復合數字。

例如,使用轉義來運行任意Perl代碼被視為作弊。 重復替換(很容易圖靈完成)也超出了范圍; 整個工作應該在正則表達式內完成。 這個問題更多的是關於正則表達式實際有多強大的界限。

注意:這些正則表達式用於PHP編寫並使用占有量詞,這些量詞在許多但不是所有語言中使用,例如java-script不支持它們。 這也是非常低效的,很快就會變得不可行。

編輯:這里是基數10 \\b(((\\d)(?=[\\d\\s]*(\\4{0,10}(n(?=.*n\\3)|nn(?=.*1\\3)|n{3}(?=.*2\\3)|n{4}(?=.*3\\3)|n{5}(?=.*4\\3)|n{6}(?=.*5\\3)|n{7}(?=.*6\\3)|n{8}(?=.*7\\3)|n{9}(?=.*8\\3))?)))+)(?![\\d\\s]*(n(?=\\4))++(..?1|(...*)\\8+1))之后我使用了base 2來簡化操作。

編輯:這個將允許您傳入一個包含幾個二進制數字的字符串,並匹配素數\\b(((\\d)(?=[\\d\\s]*(\\4{0,2}n(?=.*\\3)|\\4{0,2})))+)(?![\\d\\s]*(n(?=\\4))++(..?1|(...*)\\7+1))它基本上是通過使用邊界\\ b而不是字符串^的開頭來實現的,它允許任何數量的小數和空格向前移動到ns並包裹測試基礎的整個部分負面預測中的1個表示。 除此之外,它的工作方式與下面的相同。 例如1111 1011 nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn1匹配1011

我設法得到了我認為有用的東西(檢查到25)並且它匹配非素數。 這里是基數2(更容易解釋) ^((\\d)(?= \\d*\\s(\\3{0,2}n(?=.*\\2)|\\3{0,2})))+\\s(n(?=\\3))*+\\K(..?1|(..+?)\\6+1)這可以擴展到基數n,但這會擴展正則表達式很快。 要使這個正則表達式工作,我需要幾個條件(有點hacky),輸入字符串必須是數字后跟一個空格,后跟至少與你的數字的值一樣多的n個字符(如果你有這個數字) 10你需要在10毫秒后的皮帶上),然后是你的基數位,不包括你的0位數(例如基數10 123456789),不包括你的0.例如11 nnnnnnnnnnnnnn1 這是因為正則表達式沒有可訪問的存儲空間,所以我需要使用捕獲組來執行此操作。 最后,這個正則表達式使用/ x來忽略表達式中的空格,如果你不想使用它,則刪除所有空格。

我現在將通過3個步驟解釋它是如何工作的。 這個正則表達式分為3部分:

第1部分 :此部分將基數n> 1更改為基數1作為ns的捕獲組

這是部分^((\\d)(?= \\d*\\s(\\3{0,2}n(?=.*\\2)|\\3{0,2})))+它非常有效類似於問題中的a^nb^n示例。 前面的^表示完全匹配必須從頭開始,這對以后很重要。 這段代碼的主要結構是^((\\d)(?= \\d*\\s (suff)))+這將獲取起始空間和第一個空格之間的每個小數,並使用(\\ d)執行正向^((\\d)(?= \\d*\\s (suff)))+ (?=)其中\\ d是十進制數,(?=)是\\ d是在捕獲組()中以后的預測。 這是我們目前正在關注的數字。

前瞻的內部實際上並不是要檢查前面的狀況,而是建立一個表示我們在基數1中的數字的捕獲組。捕獲組的內部看起來像這樣

\d*\s(\3{0,2}n(?=.*\2)|\3{0,2})) 

部分\\ d * \\ s基本上將我們正在查看的字符移動到其余的剩余數字\\ d *(\\ d是數字,*是0到n盡可能多的次數)這現在讓我們看着開始的ns。

(\3{0,2}n(?=.*\2)|\3{0,2}))

是一個自引用捕獲組,這里是你最后輸入數字的需要。這個組匹配自己0到2次,但盡可能多次(使用\\ 3 {0,2}與\\ 3含義caturing group 3和{0,2}意味着匹配從0到2次)這意味着如果在當前數字之前有一個數字,則其基數1表示乘以2.對於基數10,這將是10,對於基數16,則為16如果這是第一個數字,那么該組將是未定義的,因此它將匹配0次。 然后根據我們當前正在處理的數字(使用其捕獲組)添加單個n或不添加n。 它通過使用正向前看來查看我們放置數字的輸入的結尾,n(?=。* \\ 2)這匹配n,如果它可以找到任何后面跟我們正在處理的數字。 這使它能夠識別我們正在處理的數字。 (我會用后面的看看,但它們是固定的長度)如果你有基數3並想檢查你當前正在使用的數字是2你將使用nn(?=。* 1 \\ 2)這將匹配nn只有數字是兩個。 我們使用了一個或運算符'|' 對於所有這些,如果沒有找到數字,我們假設它是0並且不添加ns。 由於這是在捕獲組中,因此該匹配將保存在組中。

在這部分的總結中,我們所做的是將每個數字向前看取前面數字的基數1表示(保存在捕獲組中)並將其乘以基數然后匹配它,然后將其添加到基數表示數字並將其保存在組中。 如果您依次為每個數字執行此操作,您將獲得該數字的基本表示。 讓我們看看和例子。 101 nnnnnnnnnnnnnnnnn1n

首先它因為^而進入了sat。 所以:101 nnnnnnnnnnnnnnnnnn1n

然后它轉到第一個數字並將其保存在捕獲摸索中1 01 nnnnnnnnnnnnnnnnnn

第2組:1

它使用\\ d * \\ s來超越所有數字和第一個空格。 1 01 n nnnnnnnnnnnnnnnnnnnnnnnnnnn

現在它正在捕獲第3組

它需要此caputing組的先前值並將其匹配0到2次

因為它是未定義的,它匹配0時間。

現在看起來再度領先,試圖找到一個數字相匹配的數字捕獲組2 1 01ñnnnnnnnnnnnnnnnn 1

因為已經發現它在捕獲組3中匹配1 n 2 1 01 nn nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

現在它離開了第3組,更新了它的值,並使前瞻性的第3組= n

它現在查看下一個數字並將其保存在捕獲組中1 0 1 nnnnnnnnnnnnnnnnnnn

組2 = 0

第3組= n

然后它也使用前瞻並轉到第一個n 1 0 1 n nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

然后它匹配組3 0到2時間,但盡可能多,所以n 1 0 1 nn nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn

然后它使用前瞻來嘗試匹配組2中的數字,它可以這樣做,因此它不會添加任何ns,返回組3和前瞻

group3 = nn

它現在查看下一個數字並將其保存在第2組中10 1 nnnnnnnnnnnnnnnnnn使用預測它將轉到ns的開頭並匹配2次第3組10 1 nnnn nnnnnnnnnnnnn然后使用預測來嘗它找到的第2組中的數字匹配a並返回第3組和前瞻。 group3 = nnnnn第3組現在包含我們號碼的基數1表示。

第2部分將ns減小到您的數字的基數1表示的大小

\s(n(?=\3))*+\K

這匹配空格然后匹配ns,只要您可以匹配前面的組3(您的號碼的基本表示)。 它通過使用占有的*來盡可能多地匹配n來做到這一點(它永遠不會讓匹配這是為了阻止匹配從以后縮小以使匹配工作)n有一個正面的預測n (?= \\ 3)這意味着只要在它前面有一個組3,n就會匹配(\\ 3給出捕獲組3)。 這使我們得到了我們的基數1表示,數字是唯一不可比擬的東西。 我們然后我們\\ K來說從這里再次開始匹配。

第3部分我們現在使用問題中提到的相同算法來獲得素數,除了我們強制它在表示的基數的開始和數字的開始之間不匹配。 你可以閱讀它是如何工作的在這里如何確定一個數字是否是正則表達式的素數?

最后,為了使它成為基礎正則表達式,你必須做一些事情

 ^((\d)(?= \d*\s(\3{0,2}n(?=.*\2)|\3{0,2})))+\s(n(?=\3))*+\K(..?1|(..+?)\6+1)

拳頭在輸入字符串的末尾添加更多數字然后更改n

?=.*\2 to  n?=.*n\2 |  n?=.*1\2   n?=.*3\2 ..,  n?=.***n**\2

最后將\\ 3 {0,2}更改為\\ 3 {0, n }。 其中n是基數。 還要記住,沒有正確的輸入字符串,這將無法工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM